[英]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
),並且將獲得所有權。
我為沒有提供解決方案而道歉,但我希望它能回答你關於兩個系統為何采取不同行為的問題。
另外,使用注冊表項來獲取此信息非常糟糕 - 使用SHGetKnownFolderPath
會更安全,更具SHGetKnownFolderPath
。 但我離題了。
根據您的操作系統版本,這可能是%ALLUSERSPROFILE%\\Application Data\\boost.interprocess
或ProgramData\\boost.interprocess
,或完全在其他地方。
你想要的並不是微不足道的,interprocess_mutex肯定是錯誤的做法。
您可以做的是通過提供卸載析構函數和/或在catch(...)中刪除終止時的互斥鎖,但這不能保證工作,因為如果直接終止進程將無法完成(來自OS)。 也可以在應用程序啟動兩次時意外刪除互斥鎖。
一種方法是在程序第一次啟動時保護進程ID(例如在共享內存中),並在程序停止時將其刪除。 每次啟動應用程序時都會讀取並檢查id是否仍在進行中,如果沒有,則啟動該程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.