我使用命名的System V信號量來鎖定OSX和Linux上的所有應用程序中的文件。根據任何定義,不是最漂亮的API。正確銷燬命名的系統V信號量
它似乎工作,但我不能完全弄清楚如何在每個人都完成後正確地銷燬信號量。
通用邏輯是這樣的:
創建:
[1]的線程或進程試圖打開信號量與()由ftok爲文件創建的key_t設置。 Set包含2個信號量。 [2]如果信號量集不存在,它將創建666個權限。 [3]「鎖定」(其中一個信號)設置爲釋放狀態(值1)。 [4]「引用計數」(同一組中的另一個信號量)遞增。
鎖定/解鎖:
要鎖定[5],線程減1,「鎖定」信號量的值(具有撤銷),從而等待如果它已經爲零。要解鎖[6],線程會將其加1,從而允許別人鎖定它。
毀:
[7] 「引用計數」 信號被試圖遞減(用IPC_NOWAIT標誌)。 [8]它的值被檢查爲0,並且如果它是[9]信號集被銷燬。
(也有基於線程本地存儲邏輯層,使一個線程內鎖遞歸)
的問題是:
- 如何同步步驟[1] [2]? (如果信號集不存在,但是當我們計算星星時,它是由其他人創建的,所以現在創建也將失敗)
- 如何將步驟[4]與[8]同步以便[9]執行不是過早地殺了我?
- 有沒有其他的比賽條件?
PS:雖然POSIX信號有更漂亮的API,我不認爲我能活下來sem_inlink()行爲如下所述:
呼叫至sem_open()來重新創建或重新 - 連接到信號量是指在調用sem_unlink()後 之後的新信號量 。
所以我沒有辦法釋放他們...
我不知道致命的缺陷:信號量的創造是原子的(我希望?)。下一個進程會實際得到它,或者最壞的情況是無法創建一個調用(應該簡單地嘗試在循環中再次獲取它)。然後,直到創建過程釋放它(設置爲1),其他人將已經存在的sem,並且如果試圖「鎖定」(用-1),他們將等待。創建過程失去控制,但沒關係,它們都是平等的。 – Eugene 2009-08-07 04:57:58
(其實這就回答我的一個問題,我只是不想循環:)) – Eugene 2009-08-07 05:01:54
至於保持一個sem,在linux上最大一般很小,比如128集。我只需要鎖定幾個文件,但是我的單元測試速度非常快 - 這是我不想使用的主要原因。 – Eugene 2009-08-07 05:07:57