检查线程是否仍在运行的可靠方法是什么?

时间:2014-03-28 11:19:53

标签: multithreading haskell

我目前正在使用以下代码来启动工作线程。

import Control.Monad      (void)
import Control.Concurrent (forkIO)
import Control.Exception  (finally)
import Data.IORef         (newIORef, writeIORef, readIORef)

startWorker :: IO a -> IO (IO Bool)
startWorker work = do
    running <- newIORef True
    _ <- forkIO $ void work `finally` writeIORef running False
    return $ readIORef running

即。开始在后台进行一些工作并返回一个IO动作,如果工作线程仍然在运行或由于某种原因它已经停止,则允许调用者轮询。

这种方法有多可靠?是否存在线程在不调用finally块的情况下死亡的情况(当然,不包括整个过程被杀死的情况)?有没有更好的方法来实现相同的功能?

2 个答案:

答案 0 :(得分:7)

异步异常可能在创建线程之后触发,但在&#34; void work`dinal`之前运行False&#34;开始了。使用forkFinally来处理。

我可以想象还有其他问题。我推荐async库。它为您处理所有复杂性。使用poll检查Async状态。

答案 1 :(得分:5)

与Yuras相关&#39;回答,初始掩蔽状态可能存在一些问题,正如Simon Marlow的书Mask and forkIO section中所解释的那样。他解释说,底线是:

  

经验法则是,使用forkIO可以更好地编写forkFinally中所谓的第一个异常处理函数。特别是,如果您发现自己最终forkIO (x撰写y),请改写forkFinally x (\_ -> y)。更好的是,使用Async API,它为您处理这些细节。