0

在不阻塞actor的情况下生成子进程的最佳方法是什么?

我的目标是运行多个命令,完成后,获取输出和退出代码。我试过这个,但显然, popen 调用被阻塞:

#!/usr/bin/env ruby

require 'celluloid/current'
require 'celluloid/io'

class MyProcessLauncher
    include Celluloid::IO

    def run
        every(1) { puts "tick" }

        every(5) {
            puts "Starting subprocess"
            ::IO.popen("sleep 10 && echo 'subprocess done'", :err=>[:child, :out]) { |io|
                puts io.read
            }
            puts $?.exitstatus
        }
    end
end

MyProcessLauncher.new.run
sleep

输出是:

tick
tick
tick
tick
Starting subprocess
subprocess done
0
tick
Starting subprocess

但我希望每个“启动子进程”之间有五个“勾号”......

谢谢 !

4

1 回答 1

2

如果需要返回值,则需要defer或使用 a 。future

defer(如果您不需要退货,这很容易)

在您的every(5)块中,使用defer包装您的popen调用(包括退出状态显示调用)defer {}

future(有点复杂)

有几种方法可以实现这种方法。我的建议是将其内容移动every(5)到它自己的方法中,并在开始时初始化一个数组@futures或类似的MyProcessLauncher东西......然后在every(5)调用中使用它:

@futures = future.new_method

此外,添加一个新循环来处理您的期货。在every(5)添加一个新的处理程序(另一个every循环,或对async递归的处理器方法的调用)来处理您的值之后,基本上是这样做的:

value = @futures.pop.value if @futures.any?

如果您遇到问题并且找不到如何处理期货的示例,我会询问有关期货的后续问题。否则,您有两种方法可以在popen不阻塞的情况下处理呼叫。

于 2016-02-08T23:34:14.180 回答