Ruby如何列出子进程的PID列表?

13

如何获取由Ruby脚本启动的所有子进程的进程ID?

4个回答

14
您可以使用以下代码获取当前进程:

process = os.getpid()

Process.pid

查看http://whynotwiki.com/Ruby_/_Process_management以获取更多详细信息。

然后,您可以使用操作系统特定的命令来获取子进程的pid。在基于Unix的系统上,这可能是以下内容之一:

# Creating 3 child processes.
IO.popen('uname')
IO.popen('uname')
IO.popen('uname')

# Grabbing the pid.
pid = Process.pid

# Get the child pids.
pipe = IO.popen("ps -ef | grep #{pid}")

child_pids = pipe.readlines.map do |line|
  parts = line.lstrip.split(/\s+/)
  parts[1] if parts[2] == pid.to_s and parts[1] != pipe.pid.to_s
end.compact

# Show the child processes.
puts child_pids

在OSX和Ubuntu上测试过。

我承认这可能不适用于所有Unix系统,因为我相信ps -ef命令的输出在不同的Unix版本中略有不同。


1
Process.pid 返回当前进程的进程标识符(PID),而非父进程。要获取父进程的PID,使用 Process.ppid - sarahhodne
只是注释中有一个错误,我们需要当前进程,因为这将是子进程的父进程。 - Jamie
6
只需几分钱:使用 "ps o pid= --ppid #{pid}" 可能比使用 "ps -ef | grep #{pid}" 更方便,而且在这种情况下您不必筛选掉不需要的行和字段。 - timurb

6

这可能是一个不错的选择,但在我的情况下,我有一个产生块的方法,跟踪所有对fork、system、spawn、backtrick等方法的调用的唯一方法是通过pid计数器链接这些方法,但我希望有更简单的方法来获取子进程的pid。 - tig

3

也可以使用sys-proctable宝石来完成:

require 'sys/proctable'

Sys::ProcTable.ps.select{ |pe| pe.ppid == $$ }

1

这实际上相当复杂,具体取决于平台。如果子进程故意试图隐藏,您实际上无法找到所有子进程。

如果您只想杀死生成的进程,有许多选项。对于测试框架,我选择了两个: 1. 使用pgid => true生成进程。 2. 插入变量MY_CUSTOM_COOKIE=asjdkahf,然后在环境中查找带有该cookie的进程并将其杀死。

请注意,使用ps查找进程层次结构非常不可靠。如果链中的一个进程退出,则其子进程会得到1的父pid(至少在Linux上是这样)。因此,它不值得实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接