Howto kill a thread in Haskell

2019-02-16 13:03发布

问题:

Using Control.Concurrent and forkIO there are some cases that will leave the thread in a blocked state (this is especially frequent under windows with networking) so even if one try to use killThread the exception is never raised in the thread. Is there any other way to force a thread to die?

My attempt to terminate the whole application with exitFailure from a helper thread don't have any effect under these conditions.

The Glorious Glasgow Haskell Compilation System, version 6.12.1 HP 2010.1.0.0

EDIT: To clear things up, I don't want to terminate the application, I would prefer to just kill the thread that have been blocked for a very long time. However there are numerous example even here at SO with complete code using the exitWith in a helper thread and that kind of scheme don't work under the conditions I have.

回答1:

To expand on my comment above, you can't interrupt blocking foreign calls. You can, however, use nonblocking IO. In the case of the Network package, this means recvLen for strings, and recvFrom for bytestrings. I assume you're always specifying the threaded runtime as well?



回答2:

One other thing to note is that GHC programs terminate when the main thread terminates. The liveness of child threads is unimportant. If you design your app such that you can always signal the main thread that it's time to terminate, it doesn't matter how blocked any child threads are.



回答3:

In Posix environments you can terminate the entire process with:

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

From the unix package. There may be a similar non-Posix feature under the Win32 package.

However, it is better to design your application such that your signalling mechanisms are respected, of course.



回答4:

You can call the ExitProcess() API from any thread in your app and the whole process, threads and all, will be terminated. There are some gotchas with some DLL detaches that can cause an issue and a process cannot be terminated until all handles for it have been released, but ExitProcess() always works fine for me as a last resort.

ExitProcess() does not care what state your threads are in. The can be blocked on I/O or running on a different processor than the thread that calls ExitProcess() - it does not matter, the OS will stop them all.

Rgds, Martin