如果有不止一种方法,请列出它们。我只知道一个,但我想知道是否有一种更清洁的、在 Ruby 中的方式。
9 回答
Process.getpgid
和方法之间的区别Process::kill
似乎是当 pid 存在但由另一个用户拥有时会发生什么。Process.getpgid
将返回答案,Process::kill
将抛出异常(Errno::EPERM)
。
基于此,我建议Process.getpgid
,如果只是因为它使您不必捕获两个不同的异常。
这是我使用的代码:
begin
Process.getpgid( pid )
true
rescue Errno::ESRCH
false
end
如果它是您希望“拥有”的进程(例如,您使用它来验证您控制的进程的 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
>>
@John T,@Dustin:实际上,伙计们,我仔细阅读了 Process rdocs,它看起来像
Process.getpgid( pid )
是应用相同技术的不那么暴力的方法。
对于子进程,其他解决方案(如发送信号)不会按预期运行:它们将表明进程在实际退出时仍在运行。
如果你想检查你自己产生的进程,你可以使用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。
这就是我一直在做的事情:
def alive?(pid)
!!Process.kill(0, pid) rescue false
end
您可以尝试使用
Process::kill 0, pid
其中 pid 是 pid 号,如果 pid 正在运行,它应该返回 1。
Linux下使用proc文件系统可以获得很多运行程序的属性:
File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
一种*nix
-only 方法是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
我之前和昨天都处理过这个问题,我将它编译到“ process_exists ”gem 中。
它将空信号 (0) 发送到具有给定 pid 的进程以检查它是否存在。即使当前用户没有将信号发送到接收进程的权限,它也可以工作。
用法:
require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)