Rubyの条件変数に関するリソースはそれほど多くありませんが、ほとんどのリソースは間違っています。ruby-docのように、ここにチュートリアルまたはここに投稿してください-それらはすべてデッドロックの可能性に苦しんでいます。
スレッドを指定された順序で開始sleep
し、同期を強制するために間にスレッドを配置することで、問題を解決できます。しかし、それは本当の問題を延期しているだけです。
私はコードを古典的な生産者/消費者問題に書き直しました:
require 'thread'
queue = []
mutex = Mutex.new
resource = ConditionVariable.new
threads = []
threads << Thread.new do
5.times do |i|
mutex.synchronize do
resource.wait(mutex)
value = queue.pop
print "consumed #{value}\n"
end
end
end
threads << Thread.new do
5.times do |i|
mutex.synchronize do
queue << i
print "#{i} produced\n"
resource.signal
end
sleep(1) #simulate expense
end
end
threads.each(&:join)
時々あなたはこれを得るでしょう(しかし常にではありません):
0 produced
1 produced
consumed 0
2 produced
consumed 1
3 produced
consumed 2
4 produced
consumed 3
producer-consumer.rb:30:in `join': deadlock detected (fatal)
from producer-consumer.rb:30:in `each'
from producer-consumer.rb:30:in `<main>'
正しい解決策は何ですか?