| Safe Haskell | Safe-Inferred |
|---|
Control.Concurrent.Extra
Description
Extra functions for Control.Concurrent. These fall into a few categories:
- Some functions manipulate the number of capabilities.
- The
forkFinallyfunction - if you need greater control of exceptions and threads see the slave-thread package. - Three new types of
MVar, namelyLock(no associated value),Var(never empty) andBarrier(filled at most once). See this blog post for more examples.
- withNumCapabilities :: Int -> IO a -> IO a
- setNumCapabilities :: Int -> IO ()
- forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId
- data Lock
- newLock :: IO Lock
- withLock :: Lock -> IO a -> IO a
- withLockTry :: Lock -> IO a -> IO (Maybe a)
- data Var a
- newVar :: a -> IO (Var a)
- readVar :: Var a -> IO a
- modifyVar :: Var a -> (a -> IO (a, b)) -> IO b
- modifyVar_ :: Var a -> (a -> IO a) -> IO ()
- withVar :: Var a -> (a -> IO b) -> IO b
- data Barrier a
- newBarrier :: IO (Barrier a)
- signalBarrier :: Barrier a -> a -> IO ()
- waitBarrier :: Barrier a -> IO a
- waitBarrierMaybe :: Barrier a -> IO (Maybe a)
Documentation
withNumCapabilities :: Int -> IO a -> IO aSource
On GHC 7.6 and above with the -threaded flag, brackets a call to setNumCapabilities.
On lower versions (which lack setNumCapabilities) this function just runs the argument action.
setNumCapabilities :: Int -> IO ()
forkFinally :: IO a -> (Either SomeException a -> IO ()) -> IO ThreadId
Lock
Like an MVar, but has no value. Used to guarantees single-threaded access, typically to some system resource. As an example:
lock <-newLocklet output =withLock. putStrLn forkIO $ do ...; output "hello" forkIO $ do ...; output "world"
Here we are creating a lock to ensure that when writing output our messages do not get interleaved. This use of MVar never blocks on a put. It is permissible, but rare, that a withLock contains a withLock inside it - but if so, watch out for deadlocks.
withLockTry :: Lock -> IO a -> IO (Maybe a)Source
Like withLock but will never block. If the operation cannot be executed
immediately it will return Nothing.
Var
Like an MVar, but must always be full. Used to on a mutable variable in a thread-safe way. As an example:
hits <-newVar0 forkIO $ do ...;modifyVar_hits (+1); ... i <-readVarhits print (HITS,i)
Here we have a variable which we modify atomically, so modifications are not interleaved. This use of MVar never blocks on a put. No modifyVar operation should ever block, and they should always complete in a reasonable timeframe. A Var should not be used to protect some external resource, only the variable contained within. Information from a readVar should not be subsequently inserted back into the Var.
modifyVar :: Var a -> (a -> IO (a, b)) -> IO bSource
Modify a Var producing a new value and a return result.
modifyVar_ :: Var a -> (a -> IO a) -> IO ()Source
Barrier
Starts out empty, then is filled exactly once. As an example:
bar <-newBarrierforkIO $ do ...; val <- ...;signalBarrierbar val print =<< waitBarrier bar
Here we create a barrier which will contain some computed value. A thread is forked to fill the barrier, while the main thread waits for it to complete. A barrier has similarities to a future or promise from other languages, has been known as an IVar in other Haskell work, and in some ways is like a manually managed thunk.
newBarrier :: IO (Barrier a)Source
Create a new Barrier.
signalBarrier :: Barrier a -> a -> IO ()Source
Write a value into the Barrier, releasing anyone at waitBarrier.
Any subsequent attempts to signal the Barrier will be silently ignored.
waitBarrier :: Barrier a -> IO aSource
Wait until a barrier has been signaled with signalBarrier.
waitBarrierMaybe :: Barrier a -> IO (Maybe a)Source
A version of waitBarrier that never blocks, returning Nothing
if the barrier has not yet been signaled.