我有以下代码:
import Control.Concurrent
sleepSort = mapM_ (forkIO . put)
where put x = threadDelay (x*10000) >> print x
这对一组整数执行睡眠排序,并且工作正常,除了一个警告:
程序按顺序打印出数据集中的每个数字,就像它应该的那样。但是,在完成打印出最后一个号码后,它会等待用户输入一些号码,然后回复该号码,然后完成。
我认为我不会在任何时候要求用户输入,为什么会发生这种情况呢?
答案 0 :(得分:7)
这是因为您的主线程不等待其他线程完成。您的程序启动 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]