1# many threads, one mutex, many condvars
2require 'thread'
3m = Mutex.new
4cv1 = ConditionVariable.new
5cv2 = ConditionVariable.new
6max = 1000
7n = 100
8waiting = 0
9scvs = []
10waiters = n.times.map do |i|
11  start_cv = ConditionVariable.new
12  scvs << start_cv
13  start_mtx = Mutex.new
14  start_mtx.synchronize do
15    th = Thread.new(start_mtx, start_cv) do |sm, scv|
16      m.synchronize do
17        sm.synchronize { scv.signal }
18        max.times do
19          cv2.signal if (waiting += 1) == n
20          cv1.wait(m)
21        end
22      end
23    end
24    start_cv.wait(start_mtx)
25    th
26  end
27end
28m.synchronize do
29  max.times do
30    cv2.wait(m) until waiting == n
31    waiting = 0
32    cv1.broadcast
33  end
34end
35waiters.each(&:join)
36