2015-11-04 84 views
1

我正在爲一組子進程編寫包裝,我想對某些信號作出響應並將它們傳播給子進程。例如,如果包裝收到QUIT,它應該發送QUIT給所有的孩子(不僅是直接的孩子,而且所有的過程都會產生)。忽略發送到我自己的進程組的信號

因此,我使用setsid,然後捕獲我想處理的信號,其代碼是kill(sig, 0)。當我這樣做時,包裝器也會再次獲取信號(作爲會話負責人和進程組內部),併產生無限循環。

我正在考慮設置某種標誌(already_handled_sig_X)並在撥打kill之前諮詢它,但(a)它看起來很笨重,(b)我什麼時候刪除標誌?

BTW:實現語言是紅寶石,所以如果你想放的例子,感覺就像在Ruby中寫他們,我會很感激它,否則 - 不用麻煩了,我能處理C.

這裏是我的目前(天真)實施:

def run_stuff(cmd) 
    fork do 
    Process.setsid 
    trap(:QUIT) { Process.kill(:QUIT, 0) } 
    trap(:TERM) { Process.kill(:TERM, 0) } 
    IO.popen(cmd) do |io| 
     while line = io.gets 
     $log.warn line 
     end 
    end 
    end 
end 

回答

1

最後,我只是設置一個標誌,忽略其他信號。上述示例代碼應該進行修改:

def run_stuff(cmd) 
    fork do 
    Process.setsid 
    shuttingdown = false 
    trap(:QUIT) do 
     next if shuttingdown 
     shuttingdown = true 
     Process.kill(:QUIT, 0) 
    end 
    trap(:TERM) do 
     next if shuttingdown 
     shuttingdown = true 
     Process.kill(:TERM, 0) 
    end 
    IO.popen(cmd) do |io| 
     while line = io.gets 
     $log.warn line 
     end 
    end 
    end 
end