2011-05-31 190 views
11

使用Control.Concurrent和forkIO會導致線程處於阻塞狀態(這在網絡連接的windows下尤其頻繁),所以即使嘗試使用killThread,異常也不會在線程中提出。 是否有任何其他方式強制線程死亡?如何殺死Haskell中的線程

我試圖從helper線程中用exitFailure終止整個應用程序,在這些條件下沒有任何效果。

光榮格拉斯哥Haskell的編譯系統,版本6.12.1 HP 2010.1.0.0

編輯:爲了澄清事實,我不想終止應用程序,我希望只殺死線程已經被封鎖了很長時間。 但是,即使在這裏,也有很多例子,在輔助線程中使用exitWith的完整代碼,並且這種方案在我所擁有的條件下不起作用。

+0

你有個例子嗎?除了被外界阻止之外,你在想什麼? – 2011-05-31 11:39:18

+0

我大概可以創建一個小例子,但在windows7/vista/2003/2008/2008r2下使用Network-ByteString(0.1.3)和recv時,recv將阻塞,直到發生某些網絡狀況。我想只是廢棄該連接並重新啓動(即超時)而不退出整個應用程序。 – Jonke 2011-06-01 07:28:07

+0

我想要的東西唐是一個poormans主管(erlang),但使用輕量級的haskell線程。我無法更改服務器,也無法使用套接字選項來超時recv,因此需要根據其他標準計算超時時間,而這些標準在程序生命週期的最後階段纔會提供。 – Jonke 2011-06-01 07:45:13

回答

3

爲了擴大我上面的評論,你不能打斷阻止外線電話。但是,您可以使用非阻塞IO。對於Network包,這意味着recvLen用於字符串,而recvFrom用於字節串。我假設你總是指定線程運行時?

+0

這是迄今爲止最接近答案的事情,但是我不能在我的特定問題中使用它。不過,我可以把套接字放在一個MVar中,並關閉我的管理程序線程中的套接字,以獲得我需要的效果,如果我將killThread調用放在關閉套接字之前。 – Jonke 2011-06-08 07:53:07

2

POSIX的環境中,您可以終止的全過程:

-- | @'exitImmediately' [email protected] calls @[email protected] to terminate the process 
-- with the indicated exit @[email protected] 
-- The operation never returns. 
exitImmediately :: ExitCode -> IO() 

the unix packageWin32 package下可能有類似的非Posix功能。

但是,最好設計一個應用程序,以便您的信號機制得到尊重,當然。

1

您可以從應用程序中的任何線程調用ExitProcess()API,並且整個過程(線程和全部)將被終止。有一些DLL可能會導致問題,並且一個進程無法終止,直到它的所有句柄都被釋放了,但ExitProcess()對我來說總是可以正常工作,作爲最後的手段。

ExitProcess()不關心你的線程處於什麼狀態。它可以在I/O上被阻塞,或者在調用ExitProcess()的線程上運行在不同的處理器上 - 沒關係,操作系統會阻止它們所有。

RGDS, 馬丁等

3

有一點要注意的是,GHC程序在主線程終止終止。兒童線的活力並不重要。如果你設計你的應用程序,以便始終可以通知主線程終止時間,則無論是如何阻止任何子線程都是如此。

+0

這是我目前'解決'的問題,但我真的只想放棄線程並重新啓動線程中的io。 – Jonke 2011-06-01 07:17:29