Multithreading Haskell中并发的奇怪行为

Multithreading Haskell中并发的奇怪行为,multithreading,sorting,haskell,sleep,Multithreading,Sorting,Haskell,Sleep,我有以下代码: import Control.Concurrent sleepSort = mapM_ (forkIO . put) where put x = threadDelay (x*10000) >> print x 这对一组整数执行休眠排序,除了一个警告外,工作正常: 程序按顺序打印出数据集中的每个数字,就像它应该打印的那样。但是,在打印完最后一个数字后,它会等待用户键入某个数字,然后将该数字回显,然后完成 我不认为我在任何时候都在请求用户输入,所以为什么会发生这

我有以下代码:

import Control.Concurrent

sleepSort = mapM_ (forkIO . put)
  where put x = threadDelay (x*10000) >> print x
这对一组整数执行休眠排序,除了一个警告外,工作正常:

程序按顺序打印出数据集中的每个数字,就像它应该打印的那样。但是,在打印完最后一个数字后,它会等待用户键入某个数字,然后将该数字回显,然后完成


我不认为我在任何时候都在请求用户输入,所以为什么会发生这种情况?

之所以会发生这种情况,是因为主线程没有等待其他线程完成。程序启动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
$
更新:您可以在
sleepSort
函数中使用信号量,而不是将调用
threadDelay
添加到
main

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]
导入控制。并发
导入控制.Concurrent.QSemN
sleepSort l=do
qsem>打印x>>信号QSEMN qsem 1
main=sleepSort[1,2,3]

您正在使用GHCi吗?如果是这样的话,它会不会表现得很古怪,好像它需要一个数字,然后再呼应一个数字?如果没有,您的
main
看起来是什么样子?如果您在GHCi中尝试此操作,请尝试键入
print
作为用户输入。是否有一种简单的方法等待其他线程完成,或者这会增加很多复杂性?