0

我是ruby面向对象语言的新手,我无法找到一种方法来完成在方法内分叉进程并将延迟输出传递给方法外使用,同时返回进程 ID。

def method(arg)
    proc_id = fork do
        var = `command #{arg}`
    end
    return both = [proc_id, var]
end

这不起作用,因为该过程尚未完成,因此var将返回。nil我怎么能完成这样的事情?

更新:

使用IO.pipe我能够完成进程间通信。但是,尝试在方法中使用此解决方案将不允许我在不首先等待进程完成的情况下返回两者proc_idvar这迫使我创建新的数组和迭代,否则这些是不必要的。fork这里的目标是在方法内部的进程仍在工作时,可以自由地在方法外部执行代码。

arg_array = ["arg1", "arg2", "arg3", "arg4"]
input = []
output = []
proc_id = []
arg_array.each_index do |i|
    input[i], output[i] = IO.pipe
    proc_id[i] = fork do
        input[i].close
        output[i].write `command #{arg_array[i]}`
    end
    output[i].close
end
command2
command3
include Process
waitpid(proc_id[0])
command4
Process.waitall
arg_array.each_index do |x|
    puts input[x].read
end
4

3 回答 3

1

你需要多花一点时间研究 fork 的概念。如果不使用 IPC(进程间通信),则 fork 后的父进程和子进程无法相互通信(交换变量),这有点复杂。

但是出于您的目的(获取子进程 ID 及其输出),使用 Open3.popen2 或 Open3.popen3 会更容易。

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html#method-c-popen2

于 2013-11-13T20:01:00.863 回答
0

如果你想开始一些事情并保存孩子 pid,那相当简单。

pid = fork
if pid
    return pid
else
    system("command #{arg}")
    exit
end

有点笨拙,但基本上,fork将子 pid 返回到父进程和nil子进程。确保您退出孩子,它不会自动执行此操作。

于 2013-11-13T18:08:31.840 回答
0

感谢jaeheung的建议,我已经解决了使用Open3.popen2(需要版本 1.9.3)。

arguments = ["arg1", "arg2", "arg3", "arg4"]
require 'open3'
include Open3
def method(arg)
    input, output, thread = Open3.popen2("command #{arg}")
    input.close
    return [thread.pid, output]
end
thread_output = []
arguments.each do |i|
    thread_output << method("#{i}")
end
command1
command2
include Process
waitpid(thread_output[0][0])
command3
Process.waitall
thread_output.each do |x|
    puts x[1].read
end
于 2013-11-15T09:32:45.393 回答