繁体   English   中英

退出Haskell程序的最佳方法是什么?

[英]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

有关更多详细信息,请参阅有关GHC并发性文档

从我的测试中,我发现了一些东西:

  1. exitFailure和朋友只能在线程0中工作。(文档实际上是这样说的,如果你去阅读它的麻烦。这些函数只是抛出异常,在其他线程中会被忽略。)

  2. 如果异常终止您的线程或整个程序,则不会刷新任何打开的句柄。 当你拼命想弄清楚你的程序崩溃的位置时,这非常令人烦恼!

所以看来如果你想在程序退出之前刷新你的东西,那么必须实现它。 只是让线程0死不会刷新东西,不抛出任何异常,只是默默地终止所有线程而不运行异常处理程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM