2010-11-25 66 views
1

大家好:)
我有一個程序有n個線程(可能很多),他們做了相當廣泛的工作。我的問題是,有時候有人關閉或重新啓動服務器(該程序在公司服務器上運行一整天),我知道有一種方法可以爲linux信號創建一個處理程序,我想知道我應該如何與之交互所有使它們使用的線程運行一個函數,然後停止工作。有辦法做到這一點?接收一個linux信號並與線程交互

遺憾的英文不好:P

回答

1

關於你能做的就是從你的信號處理函數設置一個全局變量,並讓您的線程定期檢查其價值的唯一的事情。

+0

一般來說,信號處理程序只能調用記錄爲「異步安全」的syscalls和記錄爲「可重入」的庫函數。顯然,爲程序添加線程會增加另一層限制,因此我可以理解放棄並說「在信號處理程序中除了設置變量之外不做任何事情」的誘惑,但是我覺得它有點過於強硬。 – ephemient 2010-11-25 20:12:28

1

正如其他人已經提到,信號處理會導致混亂(由於限制,特別是在多線程程序),所以最好是選擇了另一種選擇:

  • 要有處理專用線程通過sigwaitinfo發送信號 - 不過,壞消息是python似乎並不支持這種開箱即用的功能。

  • 使用特定於Linux的signalfd來處理信號(無論是在單獨的線程中還是集成到某個事件循環中) - 至少有一個您可以使用的python-signalfd模塊。

至於有沒有必要在這裏安裝信號處理程序,對你可以做什麼,當你被告知一個信號,它應該很容易完全關閉其他線程在你的程序沒有限制。

2

處理此問題的最佳方法是根本不需要任何關機操作。例如,(例如)SIGTERM或SIGQUIT的信號處理程序可以調用_exit並退出進程而不進行清理。當一個線程調用_exit(或者如果你真的想退出時),其他線程也會被停止 - 無論他們在做什麼。

這會很好,因爲它實現了只有碰撞的設計。

服務器故障設計基於機器可能在任何時候都會發生故障的原理,所以您需要能夠從這種故障中恢復,所以只需使其成爲正常的退出方式即可。無論如何你都不需要額外的代碼,因爲你的服務器應該足夠健壯。