如果有多种方法,请列出它们。我只知道一种方法,但我想知道是否有更干净、更符合Ruby的方法。
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 )
kill 0
是“暴力”的,这是一个错误。文档中写道:“如果信号是0,则不发送任何信号,但仍要进行错误检查;这可用于检查进程ID或进程组ID是否存在。” - Ray对于子进程,发送信号等其他解决方案无法按预期工作:它们会指示该进程仍在运行,而实际上已经退出。
如果您想要检查自己生成的进程,可以使用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
)。def alive?(pid)
!!Process.kill(0, pid) rescue false
end
rescue
,但在这种情况下似乎是合理的。 - Adam LassekProcess::kill 0, pid
其中pid是进程ID,如果该进程正在运行,则应返回1。
File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
我之前处理过这个问题,昨天将其编译成了 "process_exists" gem。
它向具有给定 pid 的进程发送空信号(0)来检查是否存在。即使当前用户没有权限向接收进程发送信号,它也能正常工作。
用法:
require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)
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.getpgid(pid) rescue nil).present?
=>(Process.getpgid(pid) rescue nil).present?
- Lev Lukomsky