0


0

私はhttp://www.ruby-doc.org/stdlib/libdoc/monitor/rdoc/index.htmlからの例に従い、コードを少し修正しました:

'monitor.rb'が必要です

buf = [] buf.extend(MonitorMixin)empty_cond = buf.new_cond

producer = Thread.start do#producer line = "#{Time.now}で生成"#while line buf.synchronize do put "==>#{line}" buf.push(line)empty_cond.signal end sleep(2) )#line = "#{Time.now}で制作する" #end end

ループbuf.synchronize do empty_cond.wait_while {buf.empty? item = buf.shiftは "got#{item.inspect}"を追加しますend end

プログラムを実行させます。 約5分後、それは "セグメンテーションフォルト"を投げます。 デッドロックに関連するもの

/ジャック

1 Answer


1


あなたのコードが(プロデューサーループ内のコメントアウトされたwhileステートメントで)立っているとき、プロデューサースレッドは単にループを一度だけ実行して終了します。 消費者は生成された1行をbufから読み取り、次に到着しない予定の行が来るのを待ってデッドロック状態になります。

Rubyのスレッドスケジューラにはデッドロック検出機能が組み込まれているため、「コンシューマ」ループがデッドロックしたことを確認したときにプログラムを終了します。

デッドロックを確認するには、プロデューサーをグローバル変数「+ $ producer 」に変換し、ループ文を「 $ consumer = Thread.start do …​」でラップします end + `。 コードをirbにロードして$ producerを評価すると、⇒#<Thread:0x000000010afb58 dead>(およびスリープ状態のスレッドでは$ consumer)になります。

プロデューサーのwhile-loopに関するコメントを削除すると、現在の時刻を2秒間隔で生成する作業(無限)ループができます。