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>'
什么是正确的解决方案?