6

ruby の並列/非同期処理機能を調べていて、多くの記事やブログ投稿を読みました。EventMachine、Fibers、Revactor、Reia などを調べました。残念ながら、この非常に単純なユース ケースに対する単純で効果的な (そして非 IO ブロッキング) ソリューションを見つけることができませんでした。

File.open('somelogfile.txt') do |file|
  while line = file.gets      # (R) Read from IO
    line = process_line(line) # (P) Process the line
    write_to_db(line)         # (W) Write the output to some IO (DB or file)
  end
end

ご覧のとおり、私の小さなスクリプトは、読み取り( R )、プロセス( P )、および書き込み( W ) の 3 つの操作を実行しています。簡単にするために、各操作に正確に 1 単位の時間 (たとえば 10 ミリ秒) かかるとすると、現在のコードは次のようになります (5 行)。

Time:       123456789012345 (15 units in total)
Operations: RPWRPWRPWRPWRPW

しかし、私はそれを次のようにしたいと思います:

Time:       1234567 (7 units in total)
Operations: RRRRR
             PPPPP
              WWWWW

明らかに、3 つのプロセス (リーダー、プロセッサー、ライター) を実行し、読み取り行をリーダーからプロセッサ キューに渡し、処理された行をライター キューに渡すことができます (すべて、RabbitMQ などを介して調整されます)。しかし、ユースケースは非常に単純で、適切ではありません。

(Ruby から Erlang、Closure、または Scala に切り替えることなく)これを行う方法についての手がかりはありますか?

4

2 に答える 2

3

(単一のプロセスから) 真に並列にする必要がある場合は、JRuby を使用して真のネイティブ スレッドを取得し、GIL を使用しないようにする必要があると思います。

DRb のようなものを使用して複数のプロセス/コアに処理を分散させることもできますが、ユースケースではこれは多すぎます。代わりに、複数のプロセスがパイプを使用して通信するようにすることができます。

$ cat somelogfile.txt | ruby ./proc-process | ruby ./proc-store

このシナリオでは、各ピースは並列に実行できる独自のプロセスですが、STDIN / STDOUT を使用して通信します。これはおそらく、問題に対する最も簡単な (そして最も速い) アプローチです。

# proc-process
while line = $stdin.gets do
  # do cpu intensive stuff here
  $stdout.puts "data to be stored in DB"
  $stdout.flush # this is important
end

# proc-store
while line = $stdin.gets do
  write_to_db(line)
end
于 2010-10-25T17:41:47.390 に答える
1

peach ( http://peach.rubyforge.org/ )をチェックしてください。並列の「それぞれ」を行うことは、これほど簡単ではありません。ただし、ドキュメントに記載されているように、JVM のネイティブ スレッドを使用するには、JRuby で実行する必要があります。

さまざまな Ruby インタープリターのマルチスレッド機能の詳細については、この SO の質問に対する Jorg Mittag の回答を参照してください。

于 2010-10-25T13:06:04.833 に答える