|Maintainer||Bas van Dijk <firstname.lastname@example.org> , Roel van Dijk <email@example.com>|
Standard threads extended with the ability to wait for their termination.
This module exports equivalently named functions from
Control.Concurrent. Avoid ambiguities by importing one or both
qualified. We suggest importing this module like:
import qualified Control.Concurrent.Thread as Thread ( ... )
- data ThreadId α
- threadId :: ThreadId α -> ThreadId
- forkIO :: IO α -> IO (ThreadId α)
- forkOS :: IO α -> IO (ThreadId α)
- wait :: ThreadId α -> IO (Either SomeException α)
- wait_ :: ThreadId α -> IO ()
- unsafeWait :: ThreadId α -> IO α
- unsafeWait_ :: ThreadId α -> IO ()
- status :: ThreadId α -> IO (Maybe (Either SomeException α))
- isRunning :: ThreadId α -> IO Bool
- throwTo :: Exception e => ThreadId α -> e -> IO ()
- killThread :: ThreadId α -> IO ()
is an abstract type representing a handle to a thread
that is executing or has executed a computation of type
|Eq (ThreadId α)|
|Ord (ThreadId α)|
|Show (ThreadId α)|
The new thread will be a lightweight thread; if you want to use a foreign
library that uses thread-local storage, use
GHC note: the new thread inherits the blocked state of the parent (see
forkOS instead of
forkIO makes no difference at all to the scheduling
behaviour of the Haskell runtime system. It is a common misconception that you
need to use
forkOS instead of
forkIO to avoid blocking all the Haskell
threads when making a foreign call; this isn't the case. To allow foreign calls
to be made without blocking all the Haskell threads (with GHC), it is only
necessary to use the
-threaded option when linking your program, and to make
sure the foreign import is not marked
Waiting on threads
wait but will either rethrow the exception that was thrown in the
thread or return the value that was returned by the thread.
unsafeWait in that it will rethrow the exception that was thrown in
the thread but it will ignore the value returned by the thread.
Querying thread status
Nothingif the thread is still running.
if the thread terminated normally and returned
if some exception
ewas thrown in the thread and wasn't caught.
Notice that this observation is only a snapshot of a thread's state. By the time a program reacts on its result it may already be out of date.
throwTo raises an arbitrary exception in the target thread (GHC only).
throwTo does not return until the exception has been raised in the target
thread. The calling thread can thus be certain that the target thread has
received the exception. This is a useful property to know when dealing with race
conditions: eg. if there are two threads that can kill each other, it is
guaranteed that only one of the threads will get to kill the other.
If the target thread is currently making a foreign call, then the exception will
not be raised (and hence
throwTo will not return) until the call has
completed. This is the case regardless of whether the call is inside a
Important note: the behaviour of
throwTo differs from that described in the
paper "Asynchronous exceptions in Haskell"
(http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm). In the paper,
throwTo is non-blocking; but the library implementation adopts a more
synchronous design in which
throwTo does not return until the exception is
received by the target thread. The trade-off is discussed in Section 9 of the
paper. Like any blocking operation,
throwTo is therefore interruptible (see
Section 5.3 of the paper).
There is currently no guarantee that the exception delivered by
be delivered at the first possible opportunity. In particular, a thread may
unblock and then re-
block exceptions without receiving a pending
throwTo. This is arguably undesirable behaviour.
killThread terminates the given thread (GHC only). Any work already done by
the thread isn't lost: the computation is suspended until required by another
thread. The memory used by the thread will be garbage collected if it isn't
referenced from anywhere. The
killThread function is defined in terms of
Note that this function is different than
that it blocks until the target thread is terminated:
killThread tid =