在Boost Interprocess documentation中,(匿名)进程共享的互斥类型具有进程持久性,其定义如下:
进程持久性:该机制一直持续到打开该机制的所有进程将其关闭,退出或崩溃为止。
由于这些互斥锁是匿名的,因此要共享它们,必须将它们放置在某些共享内存中(持久性更长,取决于平台的是内核还是文件系统)。
让我们考虑这个最小的例子:
namespace bi = boost::interprocess;
{
bool isMemoryCreated = /*assume function to get this info*/;
bi::shared_memory_object shm = [&]() -> bi::shared_memory_object
{
if (isMemoryCreated)
{
return {bi::open_only, "sharemem", bi::read_write};
}
else
{
bi::shared_memory_object shm{bi::create_only, "sharemem", bi::read_write};
shm.truncate(sizeof(bi::interprocess_mutex));
return shm;
}
}();
//Map the whole shared memory in this process
region = bi::mapped_region(shm, bi::read_write);
void * address = region.get_address();
bi::interprocess_mutex mutex = [&]()
{
if (isMemoryCreated)
{
return static_cast<bi::interprocess_mutex*>(address);
}
else
{
return new (address) bi::interprocess_mutex;
}
}();
std::cout << mutex->try_lock() << std::endl;
// wait on external condition
mutex->unlock();
bi::shared_memory_object::remove("sharemem");
}
以下是在macOS上运行此命令的一些结果:
如果运行 processA 直到正常完成,然后运行 processB ,则两个进程都必须创建内存并成功获取锁。这是预期的。
如果运行 processA 并“强制退出”它,则它永远不会到达清除代码以释放锁并删除内存。现在,运行 processB 内存将已经存在(isMemoryCreated
为true),这是可以预期的,因为共享内存至少具有内核持久性。但是 processB无法锁定互斥体,这似乎与boost文档矛盾:互斥体应该具有进程持久性,因此,当 processA 退出时,互斥体不应该进一步持久化
这是库中的错误吗?还是“过程持久性”意味着与之不同?
答案 0 :(得分:0)
POSIX互斥锁(用于boost :: interprocess的Linux实现中)不拥有其内存,因此其持久性就是它所驻留的内存。
代码在文件系统中的命名文件中创建一个匿名互斥体。互斥锁的持久性变为其所驻留的命名文件的持久性。
取消链接文件后,互斥体的持久性将成为进程持久性。