簡體   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