51

如果有不止一种方法,请列出它们。我只知道一个,但我想知道是否有一种更清洁的、在 Ruby 中的方式。

4

9 回答 9

62

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

基于此,我建议Process.getpgid,如果只是因为它使您不必捕获两个不同的异常。

这是我使用的代码:

begin
  Process.getpgid( pid )
  true
rescue Errno::ESRCH
  false
end
于 2010-08-25T16:43:41.193 回答
53

如果它是您希望“拥有”的进程(例如,您使用它来验证您控制的进程的 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
>> 
于 2008-11-28T05:17:26.633 回答
46

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

Process.getpgid( pid )

是应用相同技术的不那么暴力的方法。

于 2008-11-28T05:23:57.027 回答
31

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

如果你想检查你自己产生的进程,你可以使用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

于 2013-01-17T15:00:25.330 回答
6

这就是我一直在做的事情:

def alive?(pid)
  !!Process.kill(0, pid) rescue false
end
于 2015-09-10T23:44:28.787 回答
5

您可以尝试使用

Process::kill 0, pid

其中 pid 是 pid 号,如果 pid 正在运行,它应该返回 1。

于 2008-11-28T05:19:38.830 回答
4

Linux下使用proc文件系统可以获得很多运行程序的属性:

File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
于 2014-01-03T11:35:56.183 回答
0

一种*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
于 2013-09-05T14:40:28.280 回答
0

我之前和昨天都处理过这个问题,我将它编译到“ process_exists ”gem 中。

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

用法:

require 'process_exists'

pid = 12
pid_exists = Process.exists?(pid)
于 2014-08-05T18:11:06.133 回答