我是ruby
和面向对象语言的新手,我无法找到一种方法来完成在方法内部分配进程并将延迟输出传递给方法外部同时返回进程ID。
def method(arg)
proc_id = fork do
var = `command #{arg}`
end
return both = [proc_id, var]
end
这不起作用,因为var
将返回nil
,因为该过程尚未完成。我怎么能做到这样的事呢?
更新:
使用IO.pipe
我能够完成进程间通信。但是,尝试在方法中使用此解决方案将不允许我返回proc_id
和var
而不先等待进程完成,这迫使我创建新的数组和迭代,否则将不必要。这里的目标是在方法内的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
答案 0 :(得分:1)
您需要花更多时间研究fork的概念。 fork之后的父进程和子进程无法在不使用IPC(进程间通信)的情况下相互通信(交换变量),这有点复杂。
但是出于您的目的(获取子进程ID及其输出),使用Open3.popen2或Open3.popen3会更容易。
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html#method-c-popen2
答案 1 :(得分:0)
如果你想踢掉一些东西并保存孩子的pid,这很简单。
pid = fork
if pid
return pid
else
system("command #{arg}")
exit
end
有点笨拙,但基本上,fork
将子pid返回到父进程,nil
返回到子进程。确保你退出孩子,它不会自动退出。
答案 2 :(得分: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