For Development HEAD DRAFTSearch (procedure/syntax/module):

12.12 control.thread-pool - スレッドプール

Module: control.thread-pool

スレッドプールを提供します。

Class: <thread-pool>

{control.thread-pool} スレッドプールオブジェクトのクラスです。ワーカースレッドのセットを保持し、 投入されたジョブを非同期に実行します。

現在の実装では、プールのサイズ (スレッド数) は固定で、プール作成時に 指定しなければなりません。いずれスレッド数を動的に増減させる機能を 追加する予定です。

また、ジョブのキューの最大長を指定することもできます。ジョブのキューが 一杯になると、空きができるまでは新たなジョブを投入することができなくなります (下記のadd-job!参照)。

Condition type: <thread-pool-shut-down>

{control.thread-pool} スレッドプールがterminate-all!によって停止され、 新規のジョブを受け付けていないことを示すコンディションです。 <error>を継承します。次のスロットが提供されます。

Instance Variable of <thread-pool-shut-down>: pool

例外の原因となったスレッドプールオブジェクト

Function: make-thread-pool size :key (max-backlog 0)

{control.thread-pool} 大きさ(ワーカースレッド数)sizeのスレッドプールを作成して返します。 省略可能引数max-backlogによってジョブのバックログの最大値を 指定することもできます。0を与えた場合(デフォルト)は無制限です。

Function: thread-pool-results pool

{control.thread-pool} ジョブをスレッドプールに投入する際に、ジョブの結果を知る必要があるかどうかを 指定することができます。結果を要求した場合は、終了したジョブレコードが プール中の結果キュー(<mt-queue>オブジェクト)にエンキューされます。 この手続きは、プールの結果キューを返します。 <mt-queue>の詳細についてはdata.queue - キューを参照してください。

Function: thread-pool-shut-down? pool

{control.thread-pool} スレッドプールが停止され、新規のジョブを受け付けていない場合に#tを、 そうでなければ#fを返します。

Function: add-job! pool thunk :optional (need-result #f) (timeout #f)

{control.thread-pool} thunkがスレッドプールpoolのスレッドにより実行されるように設定します。 jobレコードを返します。 (control.job - 制御モジュールのための汎用ジョブ記述子参照)。

返されるjobレコードはwaitableにはなっていません。結果を知る必要が ある場合は、省略可能引数need-resultに真の値を渡してください。 そうするとジョブが終了した時点 (正常終了でも異常終了でも) で、 jobレコードがスレッドプールのresult-queueに 入るので、そのキューから結果を受け取ることができます。 need-resultを省略したり偽値を渡した場合は、ジョブが終了しても jobレコードはresult-queueに入れられません。

返されるjobレコードにはタイムスタンプが付加され、 受付時間、実行開始時間、実行終了時間が記録されます。 (ジョブがまだ実行されていなかったり、終了されていない場合は、対応する タイムスタンプは#fになっています)。 ジョブがどのくらいキューの中で待たされ、どのくらい実行にかかったかを 知るのに便利でしょう。

スレッドプールが非負のmax-backlog値を持ち、 既にその数だけジョブが待ち行列に入っている場合は、 add-job!は待ち行列に空きができるまでブロックします。 timeout引数に、実数値の秒数、あるいは絶対時刻を指定する<time> オブジェクトを渡すことでタイムアウトを指定できます。タイムアウトに 達した場合は、add-job!はジョブを作らずに#fを返します。 timeout引数を省略するか、#fを渡した場合はタイムアウトが設定されません。

(註: この動作は0.9.1から変更されました。0.9.1では、add-job!は タイムアウト引数を取らず、常にタイムアウトに0秒が指定されたかのように 振る舞っていました。現在のバージョンで同じ動作をさせるには、timeout引数 に0を明示的に渡します。)

スレッドプールが停止していた場合、この手続きは <thread-pool-shut-down>コンディションを投げます。

Function: wait-all pool :optional (timeout #f) (check-interval #e5e8)

{control.thread-pool} ジョブ待ち行列が空になり、すべての実行中のジョブも終了するまで待ちます。 終了待ちはcheck-intervalにナノ秒で指定される間隔でスレッドプールを ポールすることで行われます。すべてのジョブが終了したら#tを返します。

秒数を表す実数か、絶対時刻を表す<time>オブジェクトをtimeout 引数に渡すことで、タイムアウトを指定できます。タイムアウトに達した場合は、 wait-all#fを返します。

この手続きが呼ばれている間、新しいジョブがpoolに投入されてはなりません。

Function: terminate-all! pool :key (force-timeout #f) (cancel-queued-jobs #f)

{control.thread-pool} 投入されたジョブがすべて終了するのを待ち、すべてのスレッドを終了させます。 ひとたびこの手続きを呼ぶと、スレッドプールpoolは新規のジョブを受けつけ ません。この状態のスレッドプールに対してadd-job!を呼ぶと <thread-pool-shut-down>コンディションが投げられます。 この手続きはアプリケーションのシャットダウン時などに呼ばれることを意図しています。

デフォルトでは、この手続きはまずキューに既に投入されたジョブが全て処理されるのを 待ち、それからスレッドを穏やかに終了させます。

真の値をcancel-queued-jobs引数に与えると、キューに入っているが まだ開始されていないジョブは直ちにキャンセルされます。それらのジョブの ステータスにはkilledがセットされます。 ただし、既に開始されたジョブについてはキャンセルされません。

既に開始されたジョブも中断したい場合は、 タイムアウト値(秒数を表す実数か、絶対時刻を表す<time>オブジェクト)を force-timeout引数に渡します。 タイムアウトに達した時点で残っているスレッドは強制終了され、実行中のジョブも キャンセルされます。

スレッドの強制終了は極端な処置です。終了されるスレッドは、適切なクリーンアップを 行う機会も与えられないかもしれません。したがって通常は、 スレッドが処理中のジョブを終わらせるための適切な時間的猶予を与えるのが良いでしょう。



For Development HEAD DRAFTSearch (procedure/syntax/module):
DRAFT