Create a new channel, returning its write and read ends.
Moduleunagi-chan-0.4.1.4Haskell2010
Control.Concurrent.Chan.Unagi.NoBlocking
- 5 types
- 8 values
- Packageunagi-chan-0.4.1.4
- Exports13
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceNoBlocking.hs
General-purpose concurrent FIFO queue without blocking reads, and with optimized variants for single-threaded producers and/or consumers. This variant, and even more so the SP/SC variants, offer the lowest latency of all of the implementations in this library.
Creating channels
3 declarationsThe write end of a channel created with newChan.
The read end of a channel created with newChan.
Channel operations
0 declarationsReading
Returns immediately with an Element a future, which returns one
unique element when it becomes available via tryRead.
Note: This is a destructive operation. See Element for more details.
Note re. exceptions: When an async exception is raised during a tryReadChan
the message that the read would have returned is likely to be lost, just as
it would be when raised directly after this function returns.
readChan io c returns the next element from c, calling tryReadChan
and looping on the Element returned, and calling io at each iteration
when the element is not yet available. It throws BlockedIndefinitelyOnMVar
when isActive determines that a value will never be returned.
When used like readChan or yieldreadChan ( this is
the semantic equivalent to the blocking threadDelay 10)readChan in the other
implementations.
An IO action that returns a particular enqueued element when and if it
becomes available.
Each Element corresponds to a particular enqueued element, i.e. a returned
Element always offers the only means to access one particular enqueued
item. The value returned by tryRead moves monotonically from Nothing
to Just a when and if an element becomes available, and is idempotent at
that point.
So for instance:
(in, out) <- newChan
(el, _) <- tryReadChan out -- READ FROM EMPTY CHAN
writeChan in "msg1"
writeChan in "msg2"
readChan out -- RETURNS "msg2"
tryRead el -- RETURNS "msg1" (which would otherwise be lost)
Instances7Monad, Functor, MonadFix, MonadFail, Applicative, Alternative, …
Monad ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesFunctor ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesMonadFix ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesMonadFail ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesApplicative ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesAlternative ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.TypesMonadPlus ElementDefined in unagi-chan-0.4.1.4 · Control.Concurrent.Chan.Unagi.NoBlocking.Types
Utilities
An action that returns False sometime after the chan no longer has any
writers.
After False is returned, any tryRead which returns Nothing can
be considered to be dead. Likewise for tryReadNext. Note that in the
blocking implementations a BlockedIndefinitelyOnMVar exception is raised,
so this function is unnecessary.
Writing
Write a value to the channel.
Write an entire list of items to a chan type. Writes here from multiple threads may be interleaved, and infinite lists are supported.
Broadcasting
Duplicate a chan: the returned OutChan begins empty, but data written to
the argument InChan from then on will be available from both the original
OutChan and the one returned here, creating a kind of broadcast channel.
See also streamChan for a faster alternative that might be appropriate.
Streaming
An infinite stream of elements. tryReadNext can be called any number of
times from multiple threads, and returns a value which moves monotonically
from Pending to Next if and when a head element becomes available.
isActive can be used to determine if the stream has expired.
Constructors
StreamtryReadNext :: IO (Next a)
Constructors
Next a (Stream a)The next head element along with the tail
Stream.PendingThe next element is not yet in the queue; you can retry tryReadNext until a
Nextis returned.
Produce the specified number of interleaved "streams" from a chan. Nextuming a Stream is much faster than calling tryReadChan, and might be useful when an MPSC queue is needed, or when multiple consumers should be load-balanced in a round-robin fashion.
Usage example:
do mapM_ (writeChan i) [1..9]
[str1, str2, str2] <- streamChan 3 o
forkIO $ printStream str1 -- prints: 1,4,7
forkIO $ printStream str2 -- prints: 2,5,8
forkIO $ printStream str3 -- prints: 3,6,9
where
printStream str = do
h <- tryReadNext str
case h of
Next a str' -> print a >> printStream str'
-- We know that all values were already written, so a Pending tells
-- us we can exit; in other cases we might call yield and then
-- retry that same tryReadNext str:
Pending -> return ()
Be aware: if one stream consumer falls behind another (e.g. because it is slower) the number of elements in the queue which can't be GC'd will grow. You may want to do some coordination of Stream consumers to prevent this.