【发布时间】:2020-05-16 04:21:42
【问题描述】:
我想编写一个程序,它的主线程派生一个新线程进行计算,并等待它完成一段时间。如果子线程没有在给定时间内完成,它就会超时并被杀死。我有以下代码。
import Control.Concurrent
fibs :: Int -> Int
fibs 0 = 0
fibs 1 = 1
fibs n = fibs (n-1) + fibs (n-2)
main = do
mvar <- newEmptyMVar
tid <- forkIO $ do
threadDelay (1 * 1000 * 1000)
putMVar mvar Nothing
tid' <- forkIO $ do
if fibs 1234 == 100
then putStrLn "Incorrect answer" >> putMVar mvar (Just False)
else putStrLn "Maybe correct answer" >> putMVar mvar (Just True)
putStrLn "Waiting for result or timeout"
result <- takeMVar mvar
killThread tid
killThread tid'
我用ghc -O2 Test.hs 和ghc -O2 -threaded Test.hs 编译了上面的程序并运行了它,但是在这两种情况下程序只是挂起,没有打印任何东西或退出。如果我在if 块之前将threadDelay (2 * 1000 * 1000) 添加到计算线程,那么程序将按预期工作并在一秒钟后完成,因为计时器线程能够填充mvar。
为什么线程没有像我预期的那样工作?
【问题讨论】:
-
MVar上的注释表明它容易受到竞争条件的影响。我会认真对待那张纸条。 -
@BobDalgleish,我非常怀疑。
MVar学科在这里对我来说很好。 -
你用
+RTS -N运行程序了吗?检查wiki.haskell.org/Concurrency了解更多信息 -
这里是这种行为的一个类似示例,以及在 ghc 中主要负责大部分并发的人的回应,传奇人物 Simon :) github.com/simonmar/async/issues/93
标签: multithreading haskell concurrency timeout blocking