探したがなかったのでつくった。
require 'monitor'
class CountingSemaphore
def initialize(count)
@count = count
@monitor = Monitor.new
@zero_cond = @monitor.new_cond
end
def synchronize
@monitor.synchronize do
@zero_cond.wait_while{ @count == 0 }
@count -= 1
end
ret = yield
@monitor.synchronize do
@count += 1
@zero_cond.broadcast
end
ret
end
end
以下のように使う
cs = CountingSemaphore.new(10)
Array.new(100) do
Thread.start do
cs.synchronize{ `sleep 10` }
end
end.each(&:join)
watch --interval=1 "ps auxw | grep sleep"
(ubuntu)などとすれば最大10個であることが確認できる。