如何从Ruby检查具有特定pid的进程是否正在运行?

时间:2008-11-28 05:11:58

标签: ruby process pid

如果有多种方式,请列出。我只知道一个,但我想知道是否有一种更干净的Ruby内部方式。

8 个答案:

答案 0 :(得分:58)

Process.getpgidProcess::kill方法之间的区别似乎是pid存在但是由另一个用户拥有时会发生的情况。 Process.getpgid会返回一个答案,Process::kill会抛出异常(Errno::EPERM)

基于此,我推荐Process.getpgid,只是因为它可以避免你不必捕捉两个不同的例外。

这是我使用的代码:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end

答案 1 :(得分:46)

如果这是一个你希望“拥有”的过程(例如你用它来验证你控制的过程的pid),你可以发送sig 0给它。

>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
    from (irb):5:in `kill'
    from (irb):5
>> 

答案 2 :(得分:46)

@John T,@ Dustin:实际上,伙计们,我仔细阅读了过程rdocs,它看起来像

Process.getpgid( pid )

是一种采用相同技术的不太暴力的手段。

答案 3 :(得分:26)

对于子进程,其他解决方案(如发送信号)将不会按预期运行:它们将指示进程在实际退出时仍在运行。

如果要查看自己生成的流程,可以使用Process.waitpid。如果您使用Process::WNOHANG标志,则调用不会阻止,只要子进程没有退出,就会返回nil

示例:

pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid

如果pid不属于子进程,则会抛出异常(Errno::ECHILD: No child processes)。

同样适用于Process.waitpid2

答案 4 :(得分:4)

您可以尝试使用

Process::kill 0, pid

其中pid是pid编号,如果pid正在运行,则应返回1.

答案 5 :(得分:4)

在Linux下,您可以使用proc文件系统获取运行程序的许多属性:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")

答案 6 :(得分:0)

*nix - 唯一的方法是shell-out ps并检查返回的字符串中是否存在\n(新行)分隔符。

示例IRB输出

1.9.3p448 :067 > `ps -p 56718`                                                          
"  PID TTY           TIME CMD\n56718 ttys007    0:03.38 zeus slave: default_bundle   \n"

打包为方法

def process?(pid)  
  !!`ps -p #{pid.to_i}`["\n"]
end

答案 7 :(得分:0)

我之前处理过这个问题,昨天我把它编译成了“process_exists”宝石。

它使用给定的pid将空信号(0)发送到进程以检查它是否存在。即使当前用户没有权限将信号发送到接收进程,它也能正常工作。

用法:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)