回答
如果你在Linux或類似的東西,可考慮使用named semaphores而不是(我假設是什麼)並行線程互斥。我不認爲有一種方法可以確定pthreads互斥量的鎖定PID,而不是構建自己的註冊表並將其放入共享內存。
您應該使用操作系統提供的信號量。
操作系統釋放進程已打開的所有資源,無論它是否死亡或正常退出。
並非在所有資源。如果OP按照建議使用POSIX信號量,並且持有鎖的進程死亡,則信號量的值不會恢復,從而可能使其他進程死鎖。 – Duck 2009-11-09 19:37:13
只有當有人會有相同的想法並且會發現這個討論的使用時,我纔會退出這個錯誤的帖子!
您可以使用這種方法。 1)鎖定POSIX共享互斥鎖 2)將進程ID保存在共享內存中。 3)解鎖共享互斥 4)在正確的出口清潔過程-ID
如果進程核心轉儲下一過程會發現,在共享存儲器中有保存在步驟#2中的進程ID。如果在操作系統中沒有這個進程ID的進程,那麼沒有人擁有共享互斥。所以只需要替換進程ID。爲了回答評論
更新:
場景1:1。 開始P1 2. P1創建/打開一個名爲互斥體,如果它不存在 3. P1它timed_locks命名的互斥體和successfuly (如果需要,等待10秒); 4. P1 coredumps 5. P2在coredump後啓動 6. P2創建/打開一個已命名的互斥鎖,它存在,它是OK 7. P2 timed_locks已命名的互斥鎖並且無法鎖定(如果需要,等待10秒); 8. P2刪除命名的互斥體 9. P2再現了命名的互斥體&鎖定
我在這裏沒有看到解決方案。情況1:(1)P1鎖; (2)P1死亡; (3)死鎖。情景2:(1)P1鎖; (2)P1寫pid; (3)P1解鎖; (4)P2得到控制並鎖定並找到P1 pid。場景3:如果切換順序以便在解鎖和進程死亡之前清除pid,則可以回到最初的問題,即死進程持有鎖並使其他進程死鎖。我錯過了什麼嗎? – Duck 2009-11-09 21:42:26
評論場景#1 – 2009-11-10 16:13:31
此更新無法使用。對任意時間的依賴是不好的。但更糟糕的是,如果超過1個進程試圖執行這個公式,那麼在刪除,重新創建,鎖定等互斥量的時候,所有地獄都可能崩潰。 – Duck 2009-11-10 21:12:37
基於文件的鎖定(使用flock(2)
)如何?當持有它的過程死亡時,它們會自動釋放。
演示程序:
#include <stdio.h>
#include <time.h>
#include <sys/file.h>
void main() {
FILE * f = fopen("testfile", "w+");
printf("pid=%u time=%u Getting lock\n", getpid(), time(NULL));
flock(fileno(f), LOCK_EX);
printf("pid=%u time=%u Got lock\n", getpid(), time(NULL));
sleep(5);
printf("pid=%u time=%u Crashing\n", getpid(), time(NULL));
*(int *)NULL = 1;
}
輸出(我已經截斷了PID和次位爲清楚起見):
$ ./a.out & sleep 2 ; ./a.out
[1] 15
pid=15 time=137 Getting lock
pid=15 time=137 Got lock
pid=17 time=139 Getting lock
pid=15 time=142 Crashing
pid=17 time=142 Got lock
pid=17 time=147 Crashing
[1]+ Segmentation fault ./a.out
Segmentation fault
什麼情況是,第一個節目獲得鎖,並開始睡5秒鐘。 2秒後,程序的第二個實例開始在試圖獲取鎖的同時阻塞。 3秒鐘後,第一個程序段錯誤(bash直到後來才告訴你),第二個程序獲得鎖定並繼續。
似乎確切的答案已經以強健的互斥體的形式提供。
根據POSIX,可以使用pthread_mutexattr_setrobust()將pthread互斥鎖初始化爲「健壯」。如果持有該互斥鎖的進程死亡,下一個獲得它的線程將收到EOWNERDEAD(但仍然成功獲取互斥鎖),以便它知道執行任何清理。然後需要使用pthread_mutex_consistent()來通知獲取的互斥量再次一致。
很明顯,你需要內核和libc支持才能工作。在Linux上,內核支持被稱爲「健壯的futexes」,我發現引用了正在應用於glibc HEAD的用戶空間更新。
實際上,至少在Linux世界中,對此的支持似乎還沒有被濾除。如果這些函數不可用,您可能會發現pthread_mutexattr_setrobust_np(),就我所能收集而言,它似乎是一個提供相同語義的非POSIX前驅。我在Solaris文檔和Debian上的/usr/include/pthread.h中都找到了對pthread_mutexattr_setrobust_np()的引用。
POSIX規範可以在這裏找到:http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html
我認爲這是一個更好的答案。到目前爲止,我一直在Solaris上使用強大的互斥鎖。 – 2010-10-18 17:03:14
強大的互斥體非常棒,但請注意,如果互斥體是在父進程中創建的,然後分叉和子進程同時持有互斥鎖,它們可能無法在glibc 2.15之前的GNU/Linux上正常工作。 [bug](http://sourceware.org/bugzilla/show_bug.cgi?id=13002)在glibc 2.15中修復。如果共享互斥體的兩個進程不是由分叉創建的父代和子代,那麼即使使用舊的glibc版本,健壯的互斥體也可以正常工作。 – 2013-01-10 23:27:52
- 1. 在C++ 98互斥鎖中鎖定變量共享數據互斥鎖
- 2. 共享互斥鎖的交替例程
- 3. 1字節共享內存需要互斥鎖
- 4. C多進程訪問共享內存互斥鎖
- 5. pthread進程共享互斥死鎖
- 6. C++崩潰中的共享內存
- 7. 寫一個互斥的共享資源
- 8. 當互斥鎖不夠時?
- 9. C - 使用互斥鎖時程序崩潰或不反應
- 10. 共享內存鎖定和進程崩潰
- 11. 如何共享一組pthread的互斥鎖?
- 12. C++是互斥體鎖定共享資源的唯一方式
- 13. C++ pthreads - 嘗試鎖定互斥讀取時崩潰
- 14. std ::共享內存中的互斥量不工作
- 15. 管理共享內存中的互斥量
- 16. 共享內存併發算法與互斥鎖/信號量之間的關係
- 17. Android中的進程共享互斥鎖和條件變量
- 18. iPhone上的「互斥」和NSCondition的共享內存
- 19. 鎖定多個互斥鎖
- 20. 多線程互斥鎖可以使用多個互斥鎖
- 21. 線程與鎖定的互斥體崩潰
- 22. 調試器:如何在崩潰轉儲中獲取「互斥鎖擁有」或「無互斥鎖」信息?
- 23. Win32當進程崩潰時,不會釋放互斥體
- 24. 與CUDA共享內存互斥 - 增加項目
- 25. 互斥鎖和鎖
- 26. 鎖定可共享內存
- 27. 使用dispatch_sync作爲一個互斥鎖
- 28. boost :: asio鏈vs共享互斥的
- 29. Google App Engine中的內存緩存和互斥鎖?
- 30. 打開一個與服務共享的互斥體
一般同意信號量建議,但POSIX信號量並不真正解決問題,因爲它們也不記錄鎖定過程的PID,也不會在不合時宜的死亡情況下解鎖。雖然它們可能是SysV信號量,但生鏽和笨拙的確會跟蹤PID,並且可以在使用SEM_UNDO選項調用時恢復。 – Duck 2009-11-09 22:07:20