1

非常にシンプルな安らかなサーバーを作成しようとしています。リクエストを受信したら、現在のスレッドがクライアントにレスポンスを返している間、別のスレッドで処理できる新しいジョブをキューに作成したいと考えています。

私はシナトラを見ましたが、行き過ぎていません。

require 'sinatra'
require 'thread'

queue = Queue.new

set :port, 9090

get '/' do
  queue << 'item'
  length = queue.size
  puts 'QUEUE LENGTH %d', length
  'Message Received'
end

consumer = Thread.new do
  5.times do |i|
    value = queue.pop(true) rescue nil
    puts "consumed #{value}"
  end
end

consumer.join

上記の例では、コンシューマー スレッドが (アプリケーションの寿命とは対照的に) 数回しか実行されないことはわかっていますが、これでもうまくいきません。

より良いアプローチはありますか?

4

1 に答える 1

4

あなたの主な問題は、への呼び出しQueue#popです。を渡しtrueているため、スレッドが中断され、代わりに例外が発生します。これを でレスキューしnilます。したがって、消費者スレッドは、他のことが起こる前に 5 回ループします。

その行を次のように変更する必要があります

value = queue.pop

スレッドが新しいデータがキューにプッシュされるのを待つようにします。

consumer.joinへの呼び出しを変更するとデッドロックが発生するため、最後から行を削除する必要もありますpop

(また、それはあなたの主な問題の一部ではありませんが、キューの長さを出力するときprintfではなく、あなたが望むように見えます).puts

于 2013-04-15T20:46:39.170 に答える