Rui:ThreadLibrary:Latch

Rui:ThreadLibrary:Latch

http://gauche.svn.sourceforge.net/viewvc/gauche/Gauche-threadlib/trunk/concurrent/latch.scm

カウントダウンラッチは、条件が整うまで複数のスレッドが待つためのオブジェクトです。ラッチはカウンタを持っていて、カウンタがゼロになると、待っていたスレッドは一斉に再開させられます。一度カウンタがゼロになると、ラッチは開きっぱなしになり、スレッドがラッチを待つことはなくなります。カウンタはオブジェクトの作成時に設定されます。リセットする方法はないので、いったん開いたラッチを閉じることはできません。

ラッチの使用例は例えばこんなものが考えられます: スレッドプールを実装しているとして、テストを書きたいとしましょう。3つのタスクを与えたときにきちんと3つのスレッドが生成されて動いていることを確認したいとします。

 (let ((pool (make-thread-pool)))
   (add-task pool thunk)
   (add-task pool thunk)
   (add-task pool thunk)
   (wait pool)
   'ok)

上のコードは3つのサンクをスレッドプールに渡して実行しています。これで3つのスレッドが同時に動くことが保証できるでしょうか? それは無理です。というのも、2つめのadd-taskが呼ばれたときにはすでに最初のサンクの実行が完了していて、スレッドが再利用されるかもしれないからです。3つめのadd-taskも同じです。すべてのタスクが1つのスレッドで動く可能性があるので、3つのスレッドが動いていることのテストはこれではできません。ここで必要なのは、3つのスレッドの実行があるポイントに達するまで、サンクの終了を遅らせることです。

 (let ((pool (make-thread-pool))
       (latch (make-count-down-latch 3)))
   (define (task)
     (latch-dec! latch)
     (latch-await latch)
     (thunk))
   (add-task pool task)
   (add-task pool task)
   (add-task pool task)
   (wait pool)
   'ok)

上のコードでは、taskは3つが同時に実行されるまで終了しません。スレッドプールで3つのスレッドが同時に動いていることを正しくテストできます。

More ...