在Ruby中,我正在运行一个系统(“在这里命令”),它不断地观察文件的变化,类似于尾部。我希望我的程序继续运行而不是在system()调用时停止。 Ruby中有没有办法创建另一个进程,以便它们可以独立运行,将结果输出到终端,然后当您退出程序时,所有进程都会删除创建的应用程序?
答案 0 :(得分:2)
答案 1 :(得分: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以及其他任何地方。
答案 2 :(得分:0)
再使用Spawn投票。我们在生产中经常使用它,它非常稳定。