在Ruby中,我正在运行一个系统(“command here"),它会不断地监视文件的变化,类似于tail。我希望我的程序能继续运行,而不是在system()调用时停止。在Ruby中有没有一种方法可以创建另一个进程,这样两者都可以独立运行,将结果输出到终端,然后当您退出程序时,应用程序创建的所有进程都会被删除?
发布于 2011-08-21 06:06:20
只需结合使用spawn和waitall
spawn 'sleep 6'
spawn 'sleep 8'
Process.waitall发布于 2011-08-21 07:49:21
您不希望使用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如果您在一个终端上运行该命令,然后从另一个终端终止它(使用外壳的kill命令),您将看到子节点也被终止。如果您删除了“将此信号转发到整个进程组”的Signal.trap内容,那么一个简单的SIGTERM子进程将仍然运行。
所有这些都假设您使用的是某种Unixy系统(例如Linux或OSX)、YMMV。
发布于 2011-08-21 11:29:56
再投一票支持使用产卵。我们在生产中经常使用它,它非常稳定。
https://stackoverflow.com/questions/7134933
复制相似问题