在Ruby中告诉系统进程是否仍然存在?

时间:2011-01-17 21:47:32

标签: ruby unix

如果我按以下方式启动应用

cmd = "some_app &"
`#{cmd}`

如何判断流程是否仍然存在?我知道有各种方法 获取正在运行的应用程序的pid,然后我可以检查是否仍然可以通过 ps -ef。然而,这只会告诉我是否有一个进程存在同一个pid,当应用程序可能已经被杀死。存在同样的问题 ps -ef | grep some_app方法。

有人想要一个干净的方法来实现这个目标吗?

3 个答案:

答案 0 :(得分:4)

在一般情况下不能这样做; Unix用于操作进程的工具是有限的,并且与内核API的其余部分没有很好的集成(例如,没有办法获取进程的文件描述符,可以传递给select或类似的)。

您可以使用wait family of functions来阻止或轮询已退出的子进程。您可以为SIGCHLD安装处理程序,并在子项退出时以异步方式通知。并且,通过子进程的协作,您可以使用管道或套接字来获取有关正在发生的事情的更多详细信息。但是,由于孩子的合作活跃缺乏,你就会受到冲击(例如,孩子本身就会分叉,退出孩子,并且孙子中的setsid来电已经逃脱{ {1}}跟踪原始父级。)

除非你准备深入到系统特定代码的范围内,否则这些都是你的选择(例如,有些人用wait做了聪明的事情,通常用于调试器,以解决你正在看的各种问题 - 但我不会尝试,除非作为最后的手段。)

答案 1 :(得分:2)

在之前的项目中对此进行了研究......

显然,通常的做法是使用Process.kill(0, pid)来探测pid以查看是否 可以发送信号。只有当进程同时存在时,此方法才会返回true,调用方有权发送信号。返回值false表示该进程不存在或用户没有适当的权限或pid是错误的类型(即字符串)或...

您可以捕获表示不存在的特定异常,Errno::ESRCH,“没有此类过程”,区别于缺少权限等。

def process_exists?(pid) begin Process.kill(0, pid) rescue Errno::ESRCH # "No such process" return false rescue Errno::EPERM # "Operation not permitted" # at least the process exists return true else return true end end

显然防弹,但这是一个开始......

答案 2 :(得分:1)


$alive = true
Thread.new do
    `some_app`
    $alive = false
end

if $alive
  ...