2

An answer to this question by railscard and the doc for ConditionVariable suggest code similar to the following:

m = Mutex.new
cv = ConditionVariable.new 

Thread.new do
  sleep(3)  # A
  m.synchronize{cv.signal}
end

m.synchronize{cv.wait(m)}
puts "Resource released."  # B

This code makes the process commented as B wait until A finishes.

I understand the purpose of m.synchronize{...} around cv.wait(m). What is the purpose of m.synchronize{...} around cv.signal? How would it be different if I had the following instead?

m = Mutex.new
cv = ConditionVariable.new 

Thread.new do
  sleep(3)
  cv.signal
end

m.synchronize{cv.wait(m)}
puts "Resource released."
Community
  • 1
  • 1
sawa
  • 165,429
  • 45
  • 277
  • 381

2 Answers2

1

I think it's useless in this example, but it's required when you have any conditions or calculations before signaling to avoid race conditions.

amenzhinsky
  • 962
  • 6
  • 12
0

In order for cv in cv.wait(m) to be unlocked, the cv.signal has to be emitted after cv.wait. In this particular case, that timing is most likely guaranteed because of sleep(3), but otherwise, there is a danger of cv.signal being emitted before cv.wait(m). If that happens, there will not be any signal to be emitted after cv.wait(m), and the locked condition of cv will continue forever. The purpose of m.synchronize{...} around cv.signal is to ensure that it happens after cv.wait(m).

sawa
  • 165,429
  • 45
  • 277
  • 381