2011-08-20 73 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的投票。我们在生产中使用它很多,而且非常稳定。

相关问题