| Copyright | (c) The University of Glasgow 1994-2002 |
|---|---|
| License | see libraries/base/LICENSE |
| Maintainer | cvs-ghc@haskell.org |
| Stability | internal |
| Portability | non-portable (GHC extensions) |
| Safe Haskell | Unsafe |
| Language | Haskell2010 |
GHC.Conc
Description
Basic concurrency stuff.
AThreadId is an abstract type representing a handle to a thread.ThreadId is an instance ofEq,Ord andShow, wheretheOrd instance implements an arbitrary total ordering overThreadIds. TheShow instance lets you convert an arbitrary-valuedThreadId to string form; showing aThreadId value is occasionallyuseful when debugging or diagnosing the behaviour of a concurrentprogram.
Note: in GHC, if you have aThreadId, you essentially havea pointer to the thread itself. This means the thread itself can't begarbage collected until you drop theThreadId.This misfeature will hopefully be corrected at a later date.
forkIO ::IO () ->IOThreadIdSource#
Creates a new thread to run theIO computation passed as thefirst argument, and returns theThreadId of the newly createdthread.
The new thread will be a lightweight,unbound thread. Foreign callsmade by this thread are not guaranteed to be made by any particular OSthread; if you need foreign calls to be made by a particular OSthread, then useforkOS instead.
The new thread inherits themasked state of the parent (seemask).
The newly created thread has an exception handler that discards theexceptionsBlockedIndefinitelyOnMVar,BlockedIndefinitelyOnSTM, andThreadKilled, and passes all other exceptions to the uncaughtexception handler.
forkIOWithUnmask :: ((forall a.IO a ->IO a) ->IO ()) ->IOThreadIdSource#
LikeforkIO, but the child thread is passed a function that can be used to unmask asynchronous exceptions. This function is typically used in the following way
... mask_ $ forkIOWithUnmask $ \unmask -> catch (unmask ...) handler
so that the exception handler in the child thread is established with asynchronous exceptions masked, meanwhile the main body of the child thread is executed in the unmasked state.
Note that the unmask function passed to the child thread should only be used in that thread; the behaviour is undefined if it is invoked in a different thread.
Since: 4.4.0.0
forkOn ::Int ->IO () ->IOThreadIdSource#
LikeforkIO, but lets you specify on which capability the threadshould run. Unlike aforkIO thread, a thread created byforkOnwill stay on the same capability for its entire lifetime (forkIOthreads can migrate between capabilities according to the schedulingpolicy).forkOn is useful for overriding the scheduling policy whenyou know in advance how best to distribute the threads.
TheInt argument specifies acapability number (seegetNumCapabilities). Typically capabilities correspond to physicalprocessors, but the exact behaviour is implementation-dependent. Thevalue passed toforkOn is interpreted modulo the total number ofcapabilities as returned bygetNumCapabilities.
GHC note: the number of capabilities is specified by the+RTS -Noption when the program is started. Capabilities can be fixed toactual processor cores with+RTS -qa if the underlying operatingsystem supports that, although in practice this is usually unnecessary(and may actually degrade performance in some cases - experimentationis recommended).
Since: 4.4.0.0
forkOnWithUnmask ::Int -> ((forall a.IO a ->IO a) ->IO ()) ->IOThreadIdSource#
LikeforkIOWithUnmask, but the child thread is pinned to the given CPU, as withforkOn.
Since: 4.4.0.0
the value passed to the+RTS -N flag. This is the number of Haskell threads that can run truly simultaneously at any given time, and is typically set to the number of physical processor cores on the machine.
Strictly speaking it is better to usegetNumCapabilities, because the number of capabilities might vary at runtime.
getNumCapabilities ::IOIntSource#
Returns the number of Haskell threads that can run trulysimultaneously (on separate physical processors) at any given time. To changethis value, usesetNumCapabilities.
Since: 4.4.0.0
setNumCapabilities ::Int ->IO ()Source#
Set the number of Haskell threads that can run truly simultaneously(on separate physical processors) at any given time. The numberpassed toforkOn is interpreted modulo this value. The initialvalue is given by the+RTS -N runtime flag.
This is also the number of threads that will participate in parallelgarbage collection. It is strongly recommended that the number ofcapabilities is not set larger than the number of physical processorcores, and it may often be beneficial to leave one or more cores freeto avoid contention with other processes in the machine.
Since: 4.5.0.0
getNumProcessors ::IOIntSource#
Returns the number of CPUs that the machine has
Since: 4.5.0.0
childHandler ::SomeException ->IO ()Source#
killThread ::ThreadId ->IO ()Source#
killThread raises theThreadKilled exception in the giventhread (GHC only).
killThread tid = throwTo tid ThreadKilled
throwTo ::Exception e =>ThreadId -> e ->IO ()Source#
throwTo raises an arbitrary exception in the target thread (GHC only).
Exception delivery synchronizes between the source and target thread:throwTo does not return until the exception has been raised in thetarget thread. The calling thread can thus be certain that the targetthread has received the exception. Exception delivery is also atomicwith respect to other exceptions. Atomicity is a useful property to havewhen dealing with race conditions: e.g. if there are two threads thatcan kill each other, it is guaranteed that only one of the threadswill get to kill the other.
Whatever work the target thread was doing when the exception wasraised is not lost: the computation is suspended until required byanother thread.
If the target thread is currently making a foreign call, then theexception will not be raised (and hencethrowTo will not return)until the call has completed. This is the case regardless of whetherthe call is inside amask or not. However, in GHC a foreign callcan be annotated asinterruptible, in which case athrowTo willcause the RTS to attempt to cause the call to return; see the GHCdocumentation for more details.
Important note: the behaviour ofthrowTo differs from that described inthe 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 adoptsa more synchronous design in whichthrowTo does not return until the exceptionis 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 ofthe paper). Unlike other interruptible operations, however,throwToisalways interruptible, even if it does not actually block.
There is no guarantee that the exception will be delivered promptly,although the runtime will endeavour to ensure that arbitrarydelays don't occur. In GHC, an exception can only be raised when athread reaches asafe point, where a safe point is where memoryallocation occurs. Some loops do not perform any memory allocationinside the loop and therefore cannot be interrupted by athrowTo.
If the target ofthrowTo is the calling thread, then the behaviouris the same asthrowIO, except that the exceptionis thrown as an asynchronous exception. This means that if there isan enclosing pure computation, which would be the case if the currentIO operation is insideunsafePerformIO orunsafeInterleaveIO, thatcomputation is not permanently replaced by the exception, but issuspended as if it had received an asynchronous exception.
Note that ifthrowTo is called with the current thread as thetarget, the exception will be thrown even if the thread is currentlyinsidemask oruninterruptibleMask.
Theyield action allows (forces, in a co-operative multitasking implementation) a context-switch to any other currently runnable threads (if any), and is occasionally useful when implementing concurrency abstractions.
labelThread ::ThreadId ->String ->IO ()Source#
labelThread stores a string as identifier for this thread ifyou built a RTS with debugging support. This identifier will be used inthe debugging output to make distinction of different threads easier(otherwise you only have the thread state object's address in the heap).
Other applications like the graphical Concurrent Haskell Debugger(http://www.informatik.uni-kiel.de/~fhu/chd/) may choose to overloadlabelThread for their purposes as well.
mkWeakThreadId ::ThreadId ->IO (WeakThreadId)Source#
Make a weak pointer to aThreadId. It can be important to do this if you want to hold a reference to aThreadId while still allowing the thread to receive theBlockedIndefinitely family of exceptions (e.g.BlockedIndefinitelyOnMVar). Holding a normalThreadId reference will prevent the delivery ofBlockedIndefinitely exceptions because the reference could be used as the target ofthrowTo at any time, which would unblock the thread.
Holding aWeak ThreadId, on the other hand, will not prevent the thread from receivingBlockedIndefinitely exceptions. It is still possible to throw an exception to aWeak ThreadId, but the caller must usedeRefWeak first to determine whether the thread still exists.
Since: 4.6.0.0
The current status of a thread
Constructors
| ThreadRunning | the thread is currently runnable or running |
| ThreadFinished | the thread has finished |
| ThreadBlockedBlockReason | the thread is blocked on some resource |
| ThreadDied | the thread received an uncaught exception |
| EqThreadStatusSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync | |
| OrdThreadStatusSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync Methods compare ::ThreadStatus ->ThreadStatus ->Ordering# (<) ::ThreadStatus ->ThreadStatus ->Bool# (<=) ::ThreadStatus ->ThreadStatus ->Bool# (>) ::ThreadStatus ->ThreadStatus ->Bool# (>=) ::ThreadStatus ->ThreadStatus ->Bool# | |
| ShowThreadStatusSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync | |
Constructors
| BlockedOnMVar | blocked on |
| BlockedOnBlackHole | blocked on a computation in progress by another thread |
| BlockedOnException | blocked in |
| BlockedOnSTM | blocked in |
| BlockedOnForeignCall | currently in a foreign call |
| BlockedOnOther | blocked on some other resource. Without |
| EqBlockReasonSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync | |
| OrdBlockReasonSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync Methods compare ::BlockReason ->BlockReason ->Ordering# (<) ::BlockReason ->BlockReason ->Bool# (<=) ::BlockReason ->BlockReason ->Bool# (>) ::BlockReason ->BlockReason ->Bool# (>=) ::BlockReason ->BlockReason ->Bool# | |
| ShowBlockReasonSource# | Since: 4.3.0.0 |
Instance detailsDefined inGHC.Conc.Sync | |
threadCapability ::ThreadId ->IO (Int,Bool)Source#
Returns the number of the capability on which the thread is currently running, and a boolean indicating whether the thread is locked to that capability or not. A thread is locked to a capability if it was created withforkOn.
Since: 4.4.0.0
newStablePtrPrimMVar ::MVar () ->IO (StablePtrPrimMVar)Source#
Make a StablePtr that can be passed to the C functionhs_try_putmvar(). The RTS wants aStablePtr to the underlyingMVar#, but aStablePtr# can only refer to lifted types, so we have to cheat by coercing.
threadDelay ::Int ->IO ()Source#
Suspends the current thread for a given number of microseconds (GHC only).
There is no guarantee that the thread will be rescheduled promptly when the delay has expired, but the thread will never continue to runearlier than specified.
registerDelay ::Int ->IO (TVarBool)Source#
Switch the value of returnedTVar from initial valueFalse toTrue after a given number of microseconds. The caveats associated withthreadDelay also apply.
threadWaitRead ::Fd ->IO ()Source#
Block the current thread until data is available to read on the given file descriptor (GHC only).
This will throw anIOError if the file descriptor was closed while this thread was blocked. To safely close a file descriptor that has been used withthreadWaitRead, usecloseFdWith.
threadWaitWrite ::Fd ->IO ()Source#
Block the current thread until data can be written to the given file descriptor (GHC only).
This will throw anIOError if the file descriptor was closed while this thread was blocked. To safely close a file descriptor that has been used withthreadWaitWrite, usecloseFdWith.
threadWaitReadSTM ::Fd ->IO (STM (),IO ())Source#
Returns an STM action that can be used to wait for data to read from a file descriptor. The second returned value is an IO action that can be used to deregister interest in the file descriptor.
threadWaitWriteSTM ::Fd ->IO (STM (),IO ())Source#
Returns an STM action that can be used to wait until data can be written to a file descriptor. The second returned value is an IO action that can be used to deregister interest in the file descriptor.
Arguments
| :: (Fd ->IO ()) | Low-level action that performs the real close. |
| ->Fd | File descriptor to close. |
| ->IO () |
Close a file descriptor in a concurrency-safe way (GHC only). If you are usingthreadWaitRead orthreadWaitWrite to perform blocking I/O, youmust use this function to close file descriptors, or blocked threads may not be woken.
Any threads that are blocked on the file descriptor viathreadWaitRead orthreadWaitWrite will be unblocked by having IO exceptions thrown.
setAllocationCounter ::Int64 ->IO ()Source#
Every thread has an allocation counter that tracks how much memory has been allocated by the thread. The counter is initialized to zero, andsetAllocationCounter sets the current value. The allocation counter counts *down*, so in the absence of a call tosetAllocationCounter its value is the negation of the number of bytes of memory allocated by the thread.
There are two things that you can do with this counter:
getAllocationCounter.enableAllocationLimit.Allocation accounting is accurate only to about 4Kbytes.
Since: 4.8.0.0
getAllocationCounter ::IOInt64Source#
Return the current value of the allocation counter for the current thread.
Since: 4.8.0.0
enableAllocationLimit ::IO ()Source#
Enables the allocation counter to be treated as a limit for the current thread. When the allocation limit is enabled, if the allocation counter counts down below zero, the thread will be sent theAllocationLimitExceeded asynchronous exception. When this happens, the counter is reinitialised (by default to 100K, but tunable with the+RTS -xq option) so that it can handle the exception and perform any necessary clean up. If it exhausts this additional allowance, anotherAllocationLimitExceeded exception is sent, and so forth. Like other asynchronous exceptions, theAllocationLimitExceeded exception is deferred while the thread is insidemask or an exception handler incatch.
Note that memory allocation is unrelated tolive memory, also known asheap residency. A thread can allocate a large amount of memory and retain anything between none and all of it. It is better to think of the allocation limit as a limit onCPU time, rather than a limit on memory.
Compared to using timeouts, allocation limits don't count time spent blocked or in foreign calls.
Since: 4.8.0.0
disableAllocationLimit ::IO ()Source#
Disable allocation limit processing for the current thread.
Since: 4.8.0.0
A monad supporting atomic memory transactions.
atomically ::STM a ->IO aSource#
Perform a series of STM actions atomically.
Usingatomically inside anunsafePerformIO orunsafeInterleaveIO subverts some of guarantees that STM provides. It makes it possible to run a transaction inside of another transaction, depending on when the thunk is evaluated. If a nested transaction is attempted, an exception is thrown by the runtime. It is possible to safely useatomically insideunsafePerformIO orunsafeInterleaveIO, but the typechecker does not rule out programs that may attempt nested transactions, meaning that the programmer must take special care to prevent these.
However, there are functions for creating transactional variables that can always be safely called inunsafePerformIO. See:newTVarIO,newTChanIO,newBroadcastTChanIO,newTQueueIO,newTBQueueIO, andnewTMVarIO.
UsingunsafePerformIO inside ofatomically is also dangerous but for different reasons. SeeunsafeIOToSTM for more on this.
throwSTM ::Exception e => e ->STM aSource#
A variant ofthrow that can only be used within theSTM monad.
Throwing an exception inSTM aborts the transaction and propagates the exception.
AlthoughthrowSTM has a type that is an instance of the type ofthrow, the two functions are subtly different:
throw e `seq` x ===> throw ethrowSTM e `seq` x ===> x
The first example will cause the exceptione to be raised, whereas the second one won't. In fact,throwSTM will only cause an exception to be raised when it is used within theSTM monad. ThethrowSTM variant should be used in preference tothrow to raise an exception within theSTM monad because it guarantees ordering with respect to otherSTM operations, whereasthrow does not.
Shared memory locations that support atomic memory transactions.
newTVarIO :: a ->IO (TVar a)Source#
IO version ofnewTVar. This is useful for creating top-levelTVars usingunsafePerformIO, because usingatomically insideunsafePerformIO isn't possible.
readTVarIO ::TVar a ->IO aSource#
unsafeIOToSTM ::IO a ->STM aSource#
Unsafely performs IO in the STM monad. Beware: this is a highly dangerous thing to do.
unsafeIOToSTM, so make sure you don't acquire any resources that need releasing (exception handlers are ignored when aborting the transaction). That includes doing any IO using Handles, for example. Getting this wrong will probably lead to random deadlocks.unsafeIOToSTM can expose it.typeHandlerFun =ForeignPtrWord8 ->IO ()Source#
setHandler ::Signal ->Maybe (HandlerFun,Dynamic) ->IO (Maybe (HandlerFun,Dynamic))Source#
runHandlers ::ForeignPtrWord8 ->Signal ->IO ()Source#
setUncaughtExceptionHandler :: (SomeException ->IO ()) ->IO ()Source#
reportError ::SomeException ->IO ()Source#
Produced byHaddock version 2.20.0