繁体   English   中英

boost :: interprocess :: named_mutex vs CreateMutex

[英]boost::interprocess::named_mutex vs CreateMutex

我想从CreatMutex切换到boost::interprocess::named_mutex以将我的应用程序限制为单个实例。 当应用程序运行并且结束时,两种方法都有效。 但是,当应用程序崩溃并使用boost::interprocess::named_mutex时,不会释放锁定。 我可以通过使用两个name_mutex解决该问题,但我真的不明白这个问题。

为什么当应用程序崩溃但是它与CreatMutex一起发布时, boost::interprocess::named_mutex的锁没有被释放? 有什么不同?


boost::interprocess::named_mutex mutex(boost::interprocess::open_or_create, "my_mutex");
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(mutex, boost::interprocess::try_to_lock);
if(!lock) {
    return 1; //exit
}
//application may crash here.
boost::interprocess::named_mutex::remove("my_mutex");
return 1; //exit

警告 :我没有花费太多时间使用boost::interprocess ,所以这些信息只是来自对源的快速检查。 也就是说,我已经使用了Windows同步API了,所以这里......


两种进程间同步方法的主要区别在于对象在系统中的存在方式。

使用boost::interprocess::named_mutex以及系统特定的互斥锁,看起来同步对象在系统上创建为文件。 文件的位置基于注册表条目(参见注释1)(至少在Boost 1.54.0中)...它很可能位于Common Application Data文件夹下(参见注释2)。 当应用程序崩溃时,在您的情况下,此文件不会被删除。 我不确定这是否是设计的...但是在应用程序崩溃的情况下,最好不要弄乱文件系统, 以防万一

相反,当您使用CreateMutex ,会在内核模式下创建一个对象,对于命名的互斥锁,可以由多个应用程序访问该对象。 通过在创建Mutex时指定名称来获取Mutex的句柄,并在调用CloseHandle时丢失句柄。 当没有更多句柄引用它时,将销毁互斥对象。

其中重要的部分是在文档中

当进程终止时,系统会自动关闭句柄 当最后一个句柄关闭时,互斥对象将被销毁。

这基本上意味着Windows将在您的应用程序之后进行清理。

请注意,如果您不执行ReleaseMutex ,并且您的应用程序在它死亡时拥有互斥锁,那么等待的线程或进程可能会看到该互斥锁已被放弃( WaitForSingleObject返回WAIT_ABANDONED ),并且将获得所有权。

我为没有提供解决方案而道歉,但我希望它能回答你关于两个系统为何采取不同行为的问题。


  1. 另外,使用注册表项来获取此信息非常糟糕 - 使用SHGetKnownFolderPath会更安全,更具SHGetKnownFolderPath 但我离题了。

  2. 根据您的操作系统版本,这可能是%ALLUSERSPROFILE%\\Application Data\\boost.interprocessProgramData\\boost.interprocess ,或完全在其他地方。

你想要的并不是微不足道的,interprocess_mutex肯定是错误的做法。

您可以做的是通过提供卸载析构函数和/或在catch(...)中删除终止时的互斥锁,但这不能保证工作,因为如果直接终止进程将无法完成(来自OS)。 也可以在应用程序启动两次时意外删除互斥锁。

一种方法是在程序第一次启动时保护进程ID(例如在共享内存中),并在程序停止时将其删除。 每次启动应用程序时都会读取并检查id是否仍在进行中,如果没有,则启动该程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM