Ruby 赛璐珞非阻塞子流程
在不阻塞参与者的情况下生成子流程的最佳方法是什么 我的目标是运行多个命令,当它们完成时,获取输出和退出代码。 我试过了,但是很明显,popen呼叫被阻塞了: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" }
#!/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代码。