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

12.6 control.cseq - 並行シーケンス

Module: control.cseq

並行シーケンス (cseq) はジェネレータが別スレッドで走る遅延シーケンスです (遅延シーケンスについては遅延シーケンス参照)。 cseqを使うと、生産者-消費者型の並列性を簡単に書けます。 消費者側からは、cseqは単なるリストに見え、同期は自動的に取られます。

内部的には、同期のためにmtqueueが使われています (data.queue - キュー参照)。

Function: generator->cseq gen :key queue-length

{control.cseq} generator->lseqのように、ジェネレータから遅延シーケンスを作って返しますが、 ジェネレータgen自体は別スレッドで実行されます。

返される値は通常のリストのように見えますが、cdr方向のリストの要素は 並行して計算されます。cdrを取ろうとしてそれがまだ計算されていなければ、 読み出し側のスレッドはその値が計算されるまで待ちます。 ジェネレータgenは別スレッドで非同期に実行され、 内部キューがいっぱいになるまで値を生成し続けます。 (対比として、 通常のlseqでは、genは値が必要になった時に、読み出すスレッドで実行されます。)

genがエラーを投げた場合、それは捕捉され、 消費者がそのエラーが起きたポイントまで読み進めた時に消費者側のスレッドで再度投げられます。

省略可能な引数queue-lengthは非負の正確な整数か#fでなければなりません。 整数の場合は、内部のキューの長さを指定します。 #fの場合はライブラリのデフォルトの長さが使われます。

Gaucheのlseqは一要素先読みすることに注意してください(遅延シーケンス参照)。 キュー長を0に指定しても、genは消費者が値を呼び出す前に一回呼び出されます。

Function: coroutine->cseq proc :key queue-length

{control.cseq} coroutine->lseq (遅延シーケンスのコンストラクタ) のように、 値がprocによって生成されるlseqを返しますが、proc自体は別スレッドで 実行されます。 proc引数は、引数yieldを取る手続きです。 yield引数は1引数の手続きで、それが呼び出されると、引数に渡された値が lseqの次の要素になります。 procがリターンしたら、lseqはそこで終端となります。

procがエラーを投げた場合、それは捕捉され、 消費者がその箇所まで読み進めた時に消費者スレッドで再度投げ直されます。

省略可能な引数queue-lengthは非負の正確な整数か#fでなければなりません。 整数の場合は、内部のキューの長さを指定します。 #fの場合はライブラリのデフォルトの長さが使われます。



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