これは、メインスレッドが他のスレッドの完了を待機しないために発生します。プログラムはnスレッドを開始しますが、メインスレッドはすぐに終了し、インタプリタプロンプトに戻ります。その間、他のスレッドは出力を生成し続けます。
Prelude Control.Concurrent> sleepSort [1,2,3]
1
Prelude Control.Concurrent> 2
3
これを修正するには、メインスレッドに遅延を追加します。
Prelude Control.Concurrent> sleepSort [1,2,3] >> threadDelay 10000
1
2
3
コンパイルされたプログラムを実行している場合は、何も出力せずにすぐに終了します。
$ cat Test.hs
import Control.Concurrent
sleepSort = mapM_ (forkIO . put)
where put x = threadDelay (x*1000) >> print x
main = sleepSort [1,2,3]
$ ghc --make -O2 Test.hs
[1 of 1] Compiling Main ( Test.hs, Test.o )
Linking Test ...
$ ./Test
$
更新:threadDelay
への呼び出しを追加する代わりに、関数main
でセマフォを使用できます。sleepSort
import Control.Concurrent
import Control.Concurrent.QSemN
sleepSort l = do
qsem <- newQSemN 0
mapM_ (forkIO . put qsem) l
waitQSemN qsem n
where
n = length l
put qsem x = threadDelay (x*1000) >> print x >> signalQSemN qsem 1
main = sleepSort [1,2,3]