#forkAndWait

フォークさせた処理の完了を待つためのセマフォの名前に、semaphore1、semaphore2(追記: forGoingOn に変更済み)では味気ないので、他に何かいいのがないかなぁ…と #signal の senders of it (alt-/cmd-n) を眺めていたら、セレンディプタスに BlockContext >> #forkAndWait なるものを発見。

BlockContext >> forkAndWait
   | semaphore |
   semaphore _ Semaphore new.
   [self ensure: [semaphore signal]] fork.
   semaphore wait

いちいち書いていたものを自動的にやってくれているのですね。あと、なるほど、処理完了待ちセマフォへのシグナルは #ensure: でするのがスジなのですよね…などと学んだりしつつ。 で、これを使うと、

stream
stream _ String new writeStream. [($1 to: $3) do: [: num | stream nextPut: num. Processor yield]] fork. [($a to: $c) do: [: chr | stream nextPut: chr. Processor yield]] forkAndWait. ^ stream contents
=> '1a2b3c'

とか、

stream putSemaphore
stream _ String new writeStream. putSemaphore _ Semaphore new. [($a to: $c) do: [: chr | putSemaphore wait. stream nextPut: chr]] forkAt: Processor userSchedulingPriority + 1. [($1 to: $3) do: [: num | stream nextPut: num. putSemaphore signal]] forkAndWait. ^ stream contents
=> '1a2b3c'

などと処理終了待ちセマフォの存在を明示的にしなくてよいぶん、(うまい具合に書き換えられれば)ほぼ同じことを比較的すっきり書くことができるので、テストスクリプト向きとしては使えそう。 でも、肝心の semaphore1、semaphore2 に代わるそれらしい名前は、見つからずじまいで orz 。


むむ。semaphore for going on で、semaForGoingOn とか forGoingOn なんてどうでしょうかね。ちょっと上を書き換えてみましょう。多少なりとも意味が通じやすくなりますでしょうか。


あと、完了待ちセマフォはスレッドごとに用意するのと、ひとつを使い回すのとでどちらが分かりやすいでしょうかねぇ…。

stream forGoingOn
stream _ String new writeStream. forGoingOn _ Semaphore new. [($1 to: $3) do: [: num | stream nextPut: num. Processor yield]. forGoingOn signal] fork. [($a to: $c) do: [: chr | stream nextPut: chr. Processor yield]. forGoingOn signal] fork. forGoingOn wait; wait. ^ stream contents
=> '1a2b3c'