陷阱在被称为脚本时不起作用;但适用于IRB

时间:2013-12-09 08:58:34

标签: ruby multiprocessing exit-code

我正在尝试多个流程。当孩子完成时,我正在捕获SIGCLD以执行某些操作。它正在IRB上工作,但在我作为ruby脚本执行时却没有。

pid = fork {sleep 2; puts 'hello'}
trap('CLD') { puts "pid: #{pid} exited with code"}

当我从IRB运行上面的内容时,我会打印两行,但是当我将它作为ruby脚本运行时,陷阱过程中的行不会显示。

2 个答案:

答案 0 :(得分:2)

当您在IRB中运行代码时,主线程属于IRB,因此您调用的所有内容都存在于几乎无限的时间循环中。

在脚本执行的情况下,主线程是你自己的,它会在陷阱之前死掉。试试这个:

pid = fork {sleep 2; puts 'hello'}
trap('CLD') { puts "pid: #{pid} exited with code"}
sleep 5 # this is needed to prevent main thread to die ASAP

希望它有所帮助。

答案 1 :(得分:2)

IRB为您提供了一个外部循环,这意味着在您决定杀死它之前,ruby进程不会退出。您的ruby脚本的问题在于主要过程是在有机会捕获信号之前完成并杀死您的孩子(yikes)。

我的猜测是,这是一个测试脚本,很可能你所需的程序不会有父母在孩子面前完成的情况。要查看您的陷阱在普通的ruby脚本中工作,请在最后添加一个睡眠:

pid = fork {sleep 2; puts 'hello'}
trap('CLD') { puts "pid: #{pid} exited with code"}
sleep 3

要填充$?全局变量,您应该明确等待子进程退出:

pid = fork {sleep 2; puts 'hello'}
trap('CLD') { puts "pid: #{pid} exited with code #{$? >> 8}" }
Process.wait

如果你希望孩子在父进程死后运行,你需要一个守护进程(双叉)。