Rubyでスレッドの同時実行数を制限します。
カウンティングセマフォを使えば良いのですが、標準添付ライブラリには入ってない(多分)ので、実装します。
素直にやるとこういう感じ -> rubyでカウンティングセマフォ
カウンタとMutexを用意して、カウンタが0の時に待つ機構を作って…と、割とめんどくさいことをしないといけません。
シンプルに
標準添付ライブラリのQueueを使えばこれらの処理がサクッと実装できちゃいます。
counting.rb
require 'thread'
locks = Queue.new
2.times { locks.push :lock }
Array.new(10) do |i|
Thread.new do
lock = locks.pop
print "#{i}\n"
sleep 2
locks.push lock
end
end.each(&:join)
このコードでは10スレッド生成して2スレッドずつ実行されます。
なぜ動く?
Queueはスレッド間通信のために用意されたクラスなので、push/pop操作はatomicです。(自分でMutexを用意する必要が無い。)
また、
空のキューを読み出そうとするとスレッドが停止します
っていう素敵な仕様により、waitの実装も必要無くなります。
ただし、本来カウンタ一つで済むところで配列が用意されたりと、無駄が多い。あと、一見して何してるのかわからない。
つまり?
簡単なスクリプトでサクッと実装したいときにどうぞ!