2009-11-10 86 views
4

有沒有什麼方法可以執行POSIX共享同步對象清除,特別是在進程崩潰時?鎖定POSIX信號量解鎖是最希望的事情,但自動'收集'隊列/共享內存區域也會很好。另一個需要注意的地方是我們不能在一般情況下使用信號處理程序,因爲SIGKILL不能被捕獲。共享POSIX對象在進程結束/死亡時清除

我只看到一個選擇:一些外部守護進程接受訂閱和'保持活動'請求作爲看門狗工作,因此沒有關於某個對象的通知,它可以根據註冊策略關閉/解鎖對象。

有沒有更好的選擇/命題?我以前從來沒有認真對待POSIX共享對象(我的意見是套接字足夠滿足我的需求,而且更有用),而且我沒有找到任何適用的文章。我很樂意在這裏使用套接字,但由於歷史原因而不能使用套接字。

回答

3

您可以使用文件鎖定來協調您的進程,而不是使用信號量。文件鎖的巨大優勢在於如果進程終止,它們將被釋放。您可以將每個信號映射到共享文件中的一個字節的鎖上,並知道在退出時鎖將被釋放;在unix的大多數版本中,您鎖定的字節甚至不必存在。在Marc Rochkind的書「Advanced Unix Programming 1st edition」中有這樣的代碼,不過不知道它是否在最新的第二版中。

+0

你推薦的書非常好。 lockf()至少涵蓋了原始問題(信號量死鎖)的最危險部分)我構建的原型正常工作。 – 2009-11-13 12:53:48

+0

順便說一下,lockf()可以與第三個參數設置爲0(所有文件)一起使用。這樣它不需要任何實際的字節。至少在Linux上。 – 2009-11-13 12:55:11

2

通常的方法是與signal handlers一起使用。只需捕捉信號並調用清理功能即可。

但是你的看門狗守護進程也有一些優點。這肯定會使系統更易於理解和管理。爲了使管理更簡單,應用程序應該在守護進程沒有運行時啓動守護進程,並且守護進程應該能夠清除上次崩潰中的任何殘留。

+0

問題是,我們應該保持甚至對SIGKILL。我根據你的回答糾正了問題。什麼是守護進程我更喜歡系統服務實現,以便能夠跟蹤依賴關係。 – 2009-11-10 08:51:52

+0

你不應該試圖陷入SIGKILL。如果您的代碼中存在錯誤,則無法終止它。所以你不想那樣。你想要的是迭代所有資源並檢查它們是否仍在使用中。大多數使用SHM的應用程序都提供了清理所有共享資源的工具。我建議將這一步自動化。 – 2009-11-10 10:49:18

+1

不只是「你不應該」 - 你不能。 http://linux.die.net/man/2/signal「信號** SIGKILL **和** SIGSTOP **不能被捕獲或忽略。」 – ephemient 2009-11-10 15:36:10

2

我知道這個問題是舊的,但另一個很好的解決方案是POSIX強大的互斥體。當所有者死亡時,它們自動解鎖並進入「不一致標誌」狀態,並且下一個嘗試鎖定互斥鎖的線程獲得EOWNERDEAD錯誤,但成功成爲互斥體的新所有者。然後它可以清除互斥體所保護的任何狀態(由於先前所有者的異步終止,這可能處於非常不穩定的狀態),並在解鎖之前再次將互斥體標記爲一致。

看到這裏穩健互斥的文檔:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutex_lock.html