Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 赛璐珞非阻塞子流程_Ruby_Celluloid - Fatal编程技术网

Ruby 赛璐珞非阻塞子流程

Ruby 赛璐珞非阻塞子流程,ruby,celluloid,Ruby,Celluloid,在不阻塞参与者的情况下生成子流程的最佳方法是什么 我的目标是运行多个命令,当它们完成时,获取输出和退出代码。 我试过了,但是很明显,popen呼叫被阻塞了: #!/usr/bin/env ruby require 'celluloid/current' require 'celluloid/io' class MyProcessLauncher include Celluloid::IO def run every(1) { puts "tick" }

在不阻塞参与者的情况下生成子流程的最佳方法是什么

我的目标是运行多个命令,当它们完成时,获取输出和退出代码。 我试过了,但是很明显,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
但我预计每个“启动子流程”之间有五个“勾号”


谢谢

如果需要返回值,则需要
延迟
或使用
未来

延迟
(如果不需要返回,则很容易) 在
every(5)
块中,要使用
defer
,请将
popen
调用(包括退出状态显示调用)用
defer{}

未来
(有点复杂) 有几种方法可以实现这种方法。我的建议是将
every(5)
的内容移动到它自己的方法中,并在启动
MyProcessLauncher
时初始化数组
@futures
或类似的方法。。。然后在
每(5)
呼叫中使用此选项:

@futures = future.new_method
另外,添加一个新的循环来处理您的未来。在
every(5)
之后,添加一个新的处理程序(另一个
every
循环,或者对递归的处理器方法进行
async
调用)来处理您的值,基本上是这样做的:

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

如果你有困难,并且找不到如何处理期货的例子,我会问一个关于期货的后续问题。否则,您有两种方法可以在不阻塞的情况下处理
popen
调用。

您得到了什么输出?用输出更新问题。谢谢!两种方法都很有效。我还找到了另一个解决方案,使用一个专用的Actor池来运行popen代码。