Maintainer | Bas van Dijk <v.dijk.bas@gmail.com> , Roel van Dijk <vandijk.roel@gmail.com> |
---|
Standard threads extended with the ability to wait for their termination.
This module exports equivalently named functions from Control.Concurrent
(and GHC.Conc
). Avoid ambiguities by importing this module qualified. May
we suggest:
import qualified Control.Concurrent.Thread as Thread ( ... )
- data Result α
- forkIO :: IO α -> IO (ThreadId, Result α)
- forkOS :: IO α -> IO (ThreadId, Result α)
- forkOnIO :: Int -> IO α -> IO (ThreadId, Result α)
- wait :: Result α -> IO (Either SomeException α)
- wait_ :: Result α -> IO ()
- unsafeWait :: Result α -> IO α
- unsafeWait_ :: Result α -> IO ()
- status :: Result α -> IO (Maybe (Either SomeException α))
- isRunning :: Result α -> IO Bool
The result of a thread
Forking threads
forkIO :: IO α -> IO (ThreadId, Result α)Source
Sparks off a new thread to run the given IO
computation and returns the
ThreadId
of the newly created thread paired with the Result
of the thread
which can be
upon.
wait
ed
The new thread will be a lightweight thread; if you want to use a foreign
library that uses thread-local storage, use forkOS
instead.
GHC note: the new thread inherits the blocked state of the parent (see
block
).
forkOS :: IO α -> IO (ThreadId, Result α)Source
Like forkIO
, this sparks off a new thread to run the given IO
computation
and returns the ThreadId
of the newly created thread paired with the Result
of the thread which can be
upon.
wait
ed
Unlike forkIO
, forkOS
creates a bound thread, which is necessary if you
need to call foreign (non-Haskell) libraries that make use of thread-local
state, such as OpenGL (see Control.Concurrent
).
Using 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 unsafe
.
forkOnIO :: Int -> IO α -> IO (ThreadId, Result α)Source
Like forkIO
, but lets you specify on which CPU the thread is
created. Unlike a forkIO
thread, a thread created by forkOnIO
will stay on the same CPU for its entire lifetime (forkIO
threads
can migrate between CPUs according to the scheduling policy).
forkOnIO
is useful for overriding the scheduling policy when you
know in advance how best to distribute the threads.
The Int
argument specifies the CPU number; it is interpreted modulo
numCapabilities
(note that it actually specifies a capability number
rather than a CPU number, but to a first approximation the two are
equivalent).
Waiting for results
unsafeWait :: Result α -> IO αSource
Like wait
but will either rethrow the exception that was thrown in the
thread or return the value that was returned by the thread.
unsafeWait_ :: Result α -> IO ()Source
Like 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 results
status :: Result α -> IO (Maybe (Either SomeException α))Source
A non-blocking wait
.
- Returns
Nothing
if the thread is still running. - Returns
if the thread terminated normally and returnedJust
(Right
x)x
. - Returns
if some exceptionJust
(Left
e)e
was 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.