Ruby运行两个进程,将结果输出到终端,并安全结束

时间:2011-08-20 21:53:29

标签: ruby multithreading process

在Ruby中,我正在运行一个系统(“在这里命令”),它不断地观察文件的变化,类似于尾部。我希望我的程序继续运行而不是在system()调用时停止。 Ruby中有没有办法创建另一个进程,以便它们可以独立运行,将结果输出到终端,然后当您退出程序时,所有进程都会删除创建的应用程序?

3 个答案:

答案 0 :(得分:2)

只需合并spawnwaitall

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

答案 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投票。我们在生产中经常使用它,它非常稳定。