Maintainer | Bas van Dijk <[email protected]> , Roel van Dijk <[email protected]> |
---|
Control.Concurrent.Thread
Contents
Description
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 ( ... )
The following is an example how to use this module:
import qualified Control.Concurrent.Thread as Thread (forkIO
,result
) main = do (tid, wait) <- Thread.forkIO
$ do x <- someExpensiveComputation return x doSomethingElse x <- Thread.result
=<<wait
doSomethingWithResult x
Forking threads
forkIO :: IO α -> IO (ThreadId, IO (Result α))Source
Sparks off a new thread to run the given IO
computation and returns the
ThreadId
of the newly created thread paired with an IO computation that waits
for the result of the thread.
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, IO (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 an IO
computation that waits for the result of the thread.
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, IO (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).
forkIOUnmasked :: IO α -> IO (ThreadId, IO (Result α))Source
Like forkIO
, but the child thread is created with asynchronous exceptions
unmasked (see Control.Exception.mask
).
Results
type Result α = Either SomeException αSource
A result of a thread is either some exception that was thrown in the thread and wasn't catched or the actual value that was returned by the thread.
result :: Result α -> IO αSource
Retrieve the actual value from the result.
When the result is SomeException
the exception is thrown.