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