2011-08-20 66 views
1

在Ruby中,我運行了一個系統(「command here」),它不斷監視文件的變化,類似於尾部。我希望我的程序繼續運行,而不是在system()調用中停止。 Ruby中有沒有辦法創建另一個進程,以便兩者都可以獨立運行,將結果輸出到終端,然後當您退出程序時,創建的應用程序的所有進程都將被刪除?Ruby運行兩個進程,將結果輸出到終端,並安全結束

+0

當程序退出時是否想要殺死所有的子進程,或者是否希望在退出之前等待子進程完成? –

+0

程序退出時終止所有子進程。兩個進程都在監視文件的變化,所以兩者都不會完成。 – jaysonp

回答

2

只是結合spawnwaitall

spawn 'sleep 6' 
spawn 'sleep 8' 
Process.waitall 
2

你不想使用system作爲等待過程來完成。您可以使用spawn,然後使用wait(避開殭屍)。然後,當你想退出時,發送一個SIGTERM到你產生的進程。您也可以使用fork來啓動您的子進程,但如果您使用外部程序,則spawn可能更容易。

您也可以使用進程組而不是跟蹤所有進程ID,然後一個Process.kill('TERM', -process_group_id)調用將處理事情。您的子進程應該在同一個進程組中結束,但如果您需要,則有Process.setpgid

下面是一個使用fork(更容易將它全部封裝在一個包中)的示例。

def launch(id, sleep_for) 
    pid = Process.fork do 
     while(true) 
      puts "#{id}, pgid = #{Process.getpgid(Process.pid())}, pid = #{Process.pid()}" 
      sleep(sleep_for) 
     end 
    end 
    # No zombie processes please. 
    Process.wait(pid, Process::WNOHANG) 
    pid 
end 

# These just forward the signals to the whole process group and 
# then immediately exit. 
pgid = Process.getpgid(Process.pid()) 
Signal.trap('TERM') { Process.kill('TERM', -pgid); exit } 
Signal.trap('INT') { Process.kill('INT', -pgid); exit } 

launch('a', 5) 
launch('b', 3) 
while(true) 
    puts "p, pgid = #{Process.getpgid(Process.pid())}, pid = #{Process.pid()}" 
    sleep 2 
end 

如果運行在一個終端,然後從另一個殺死它(使用shell的kill命令),你會看到,孩子們也被打死。如果你刪除了「將這個信號轉發給整個過程組」Signal.trap的東西,那麼一個簡單的SIGTERM會讓這些孩子仍然在運行。

所有這些都假設你正在某種Unixy系統(例如Linux或OSX),YMMV等其他地方工作。

0

還有一次使用Spawn的投票。我們在生產中使用它很多,而且非常穩定。

相關問題