2011-04-01 21 views
0

我在Managing Signal Handling for daemons that fork()中找到了答案,對我正在做的事情非常有幫助。我不知道如何解決Perl:在分支子代中安裝信號處理程序,其執行者

「你會因此不需要安裝任何的信號處理在execed進程啓動時」

我沒有在那個啓動過程控制向上。有沒有辦法讓我強制從叉子的父母那裏得到exec的某些信號手柄?

編輯: {
我正在寫一個Perl模塊來監視長時間運行的進程。取而代之的

system(<long-running cmd>); 

你會使用

my_system(<ID>, <long-running cmd>); 

我創建了一個<ID>鎖定文件,不要讓其他my_system(<ID>...)通過電話,如果有一個當前具有匹配ID運行。

上級分支/管理員<long-running cmd>並且在終止時清除鎖定文件。我想讓孩子自給自足,以便父母可以退出(或者如果父母得到kill -9,孩子可以自己照顧自己)。
}

回答

2

在Unix系統上,你可以讓exec'd進程忽略信號(除非進程選擇覆蓋你說的話),但是你不能強迫它爲它設置一個處理程序。你可以做的最多的是讓相關信號由默認處理程序處理。

如果你仔細想想,你會明白爲什麼。要安裝一個信號處理程序,你必須提供一個函數指針 - 但是exec()的程序不能指定它的一個函數,因爲它們不會作爲exec'd進程的一部分存在,並且它不能指定其中一個執行過程的功能是因爲它們不作爲執行過程的一部分存在。同樣,您不能在執行過程中註冊atexit()處理程序,該程序將由執行過程執行。

至於編程問題,有一個很好的理由,即鎖文件通常包含持有鎖的進程的進程ID(pid)它可以讓你檢查這個過程是否還在,即使它不是你的孩子。您可以從鎖定文件中讀取pid,然後使用kill(pid, 0),它會告訴您過程是否存在,您可以發送信號而不實際發送任何信號。

+0

很好的答案。我希望能有辦法以某種方式將處理函數加載到正在運行的程序中......太糟糕了,這是不可能的。另外,lockfile的這個方案几乎可以隨時爲我的情況工作。唯一的問題是有很多計算機共享一個nfs文件系統。因此,如果從A啓動了鎖,則B無法查看它是否仍在運行,或者它是否是掛鎖文件。 – ajwood 2011-04-02 14:30:27

1

一種方法是使用兩個叉子。

第一個分支將創建一個子進程負責清理鎖定文件,如果父母死亡。這個過程也將分叉孫子,這將執行長期運行的命令。

+0

這真的有幫助嗎?你仍然可以'殺死'第一把叉子來解決問題。 – ajwood 2011-04-03 00:17:55