[英]What's the best way to exit a Haskell program?
我有一个使用多个线程的程序。 据我了解,当线程0退出时,整个程序退出,无论其他线程可能仍在运行。
问题是,这些其他线程可能有文件打开。 当然,这包含在异常处理代码中,以便在出现问题时干净地关闭文件。 这也意味着如果我使用killThread
(通过throwTo
实现),该文件也应该在线程退出之前关闭。
我的问题是,如果我只是让线程0退出,而不试图阻止其他线程,那么各种文件句柄是否会被很好地关闭? 是否刷新了任何缓冲输出?
简而言之,我可以退出,还是我需要先手动杀死线程?
您可以使用Control.Concurrent.MVar
来实现此目的。 MVar
本质上是一个“空”或“满”的标志。 一个线程可以尝试读取一个MVar
,如果它是空的,它会阻塞该线程。 只要你有一个执行文件IO的线程,就为它创建一个MVar
,然后将它传递给MVar
作为参数。 将您创建的所有MVar
放入列表中:
main = do
let mvars = sequence (replicate num_of_child_threads newEmptyMVar)
returnVals <- sequence (zipWith (\m f -> f m)
mvars
(list_of_child_threads :: [MVar -> IO a]))
一旦子线程完成了您担心的所有文件操作,请写入MVar
。 你可以做而不是编写killThread
mapM_ takeMVar mvars >> killThread
而且你的线程会在哪里退出,只需要拿走所有的MVar
。
从我的测试中,我发现了一些东西:
exitFailure
和朋友只能在线程0中工作。(文档实际上是这样说的,如果你去阅读它的麻烦。这些函数只是抛出异常,在其他线程中会被忽略。)
如果异常终止您的线程或整个程序,则不会刷新任何打开的句柄。 当你拼命想弄清楚你的程序崩溃的位置时,这非常令人烦恼!
所以看来如果你想在程序退出之前刷新你的东西,那么你必须实现它。 只是让线程0死不会刷新东西,不抛出任何异常,只是默默地终止所有线程而不运行异常处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.