EventMachine可以识别所有线程是否已完成?

时间:2012-09-13 07:12:33

标签: ruby asynchronous eventmachine

我是EM新手并编写两个代码来比较同步和异步IO。我正在使用Ruby 1.8.7。

同步IO的示例是:

def pause_then_print(str)
  sleep 2
  puts str
end

5.times { |i| pause_then_print(i) }

puts "Done"

这可以按预期工作,需要10秒才能终止。

另一方面,异步IO的示例是:

require 'rubygems'
require 'eventmachine'

def pause_then_print(str)
  Thread.new do
    EM.run do
      sleep 2
      puts str
    end
  end
end

EventMachine.run do
  EM.add_timer(2.5) do
    puts "Done"
    EM.stop_event_loop
  end
  EM.defer(proc do
    5.times { |i| pause_then_print(i) }
  end)
end

在2秒内显示5个数字。

现在我明确地编写了代码,要求在2.5秒后停止EM事件循环。但我想要的是程序在打印出5个数字后立即终止。为此,我认为EventMachine应该识别所有5个线程已完成,然后停止事件循环。

我该怎么做?另外,如果异步IO示例更加自然和富有表现力,请更正它。

提前致谢。

1 个答案:

答案 0 :(得分:1)

有关您的异步代码的一些信息。 EM.defer安排代码在线程上执行。然后,您将创建更多线程。当您在创建循环中使用EM.defer时,没有太多意义。这有一个额外的好处,EM将从它的内部线程池服务线程,由于没有线程创建开销,它应该更快一点。 (请注意,我相信EM线程池中有20个线程,因此您希望保持低于该数字)。像下面的东西应该工作(虽然我还没有测试过)

require 'rubygems'
require 'eventmachine'

def pause_then_print(str)
  sleep 2
  puts str
end

EventMachine.run do
  EM.add_timer(2.5) do
    puts "Done"
    EM.stop_event_loop
  end
  5.times do |i|
    EM.defer { pause_then_print(i) }
  end
end

在检测工作何时完成时,您可以EM.defer在其操作完成时执行回调。所以,你可以在那里添加一些代码,在i == 4或类似的东西时添加回调。有关如何添加回调的信息,请参阅EM文档:EM.defer