0

私は EM 初心者で、同期 IO と非同期 IO を比較するために 2 つのコードを書いています。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.x 秒で 5 つの数字が表示されます。

ここで、EM イベント ループが 2.5 秒後に停止するようにコードを明示的に記述しました。しかし、私が望むのは、プログラムが 5 つの数字を出力した直後に終了することです。EventMachineそのためには、5 つのスレッドがすべて完了したことを認識してから、イベント ループを停止する必要があると思います。

どうやってやるの?また、非同期 IO の例がより自然で表現力に富んでいる場合は、修正してください。

前もって感謝します。

4

1 に答える 1

1

Async コードに関するいくつかのこと。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、操作が完了したときにコールバックを実行できます。そのため、コールバック when などを追加するコードを少し入れることができますi == 4。コールバックを追加する方法については、EM ドキュメントを参照してください: EM.defer

于 2012-12-06T05:02:20.103 に答える