std.concurrency

This is a low-level messaging API upon which more structured or restrictive APIs may be built. The general idea is that every messageable entity is represented by a common handle type called a Tid, which allows messages to be sent to logical threads that are executing in both the current process and in external processes using the same interface. This is an important aspect of scalability because it allows the components of a program to be spread across available resources with few to no changes to the actual implementation.

A logical thread is an execution context that has its own stack and which runs asynchronously to other logical threads. These may be preemptively scheduled kernel threads, fibers (cooperative user-space threads), or some other concept with similar behavior.

The type of concurrency used when logical threads are created is determined by the Scheduler selected at initialization time. The default behavior is currently to create a new kernel thread per call to spawn, but other schedulers are available that multiplex fibers across the main thread or use some combination of the two approaches.

Module Deinitializers 1

static ~this()

Types 18

standard
priority
linkDead
structMessage
Fields
MsgType type
Variant data
Methods
@property auto convertsTo(T...)()
@property auto get(T...)()
auto map(Op)(Op op)
Constructors
this(MsgType t, T vals)
classMessageMismatch : Exception

Thrown on calls to receiveOnly if a message other than the type the receiving thread expected is sent.

Constructors
this(string msg = "Unexpected message type")
classOwnerTerminated : Exception

Thrown on calls to receive if the thread that spawned the receiving thread has terminated and no more messages exist.

Fields
Tid tid
Constructors
this(Tid t, string msg = "Owner terminated")
classLinkTerminated : Exception

Thrown if a linked thread has terminated.

Fields
Tid tid
Constructors
this(Tid t, string msg = "Link terminated")
classPriorityMessageException : Exception

Thrown if a message was sent to a thread via

prioritySend and the receiver does not have a handler

for a message of this type.

Fields
Variant messageThe message that was sent.
Constructors
classMailboxFull : Exception

Thrown on mailbox crowding if the mailbox is configured with OnCrowding.throwException.

Fields
Tid tid
Constructors
this(Tid t, string msg = "Mailbox full")
classTidMissingException : Exception

Thrown when a Tid is missing, e.g. when ownerTid doesn't find an owner thread.

structTid

An opaque type used to represent a logical thread.

Fields
Methods
void toString(W)(ref W w) constGenerate a convenient string for identifying this `Tid`. This is only useful to see if `Tid`'s that are currently executing are the same or different, e.g. for logging and debugging. It is potent...
Constructors

These behaviors may be specified when a mailbox is full.

blockWait until room is available.
throwExceptionThrow a MailboxFull exception.
ignoreAbort the send and return.

Encapsulates all implementation-level data needed for scheduling.

When defining a Scheduler, an instance of this struct must be associated with each logical thread. It contains all implementation-level information needed by the internal API.

Fields
Tid ident
bool[Tid] links
Tid owner
Methods
static @property ref thisInfo() nothrowGets a thread-local instance of `ThreadInfo`.
void cleanup()Cleans up this ThreadInfo.
interfaceScheduler

A Scheduler controls how threading is performed by spawn.

Implementing a Scheduler allows the concurrency mechanism used by this module to be customized according to different needs. By default, a call to spawn will create a new kernel thread that executes the supplied routine and terminates when finished. But it is possible to create Schedulers that reuse threads, that multiplex Fibers (coroutines) across a single thread, or any number of other approaches. By making the choice of Scheduler a user-level option, std.concurrency may be used for far more types of application than if this behavior were predefined.

Example:

import std.concurrency;
import std.stdio;

void main()
{
   scheduler = new FiberScheduler;
   scheduler.start(
   {
       writeln("the rest of main goes here");
   });
}

Some schedulers have a dispatching loop that must run if they are to work properly, so for the sake of consistency, when using a scheduler, start() must be called within main(). This yields control to the scheduler and will ensure that any spawned threads are executed in an expected manner.

Methods
void start(void delegate() op)Spawns the supplied op and starts the `Scheduler`.
void spawn(void delegate() op)Assigns a logical thread to execute the supplied op.
void yield() nothrow;Yields execution to another logical thread.
ThreadInfo thisInfo() @property ref nothrow;Returns an appropriate `ThreadInfo` instance.
Condition newCondition(Mutex m) nothrow;Creates a `Condition` variable analog for signaling.

An example Scheduler using kernel threads.

This is an example Scheduler that mirrors the default scheduling behavior of creating one kernel thread per call to spawn. It is fully functional and may be instantiated and used, but is not a necessary part of the default functioning of this module.

Methods
void start(void delegate() op)This simply runs op directly, since no real scheduling is needed by this approach.
void spawn(void delegate() op)Creates a new kernel thread and assigns it to run the supplied op.
void yield() nothrowThis scheduler does no explicit multiplexing, so this is a no-op.
ThreadInfo thisInfo() @property ref nothrowReturns `ThreadInfo.thisInfo`, since it is a thread-local instance of `ThreadInfo`, which is the correct behavior for this scheduler.
Condition newCondition(Mutex m) nothrowCreates a new `Condition` variable. No custom behavior is needed here.

An example Scheduler using Fibers.

This is an example scheduler that creates a new Fiber per call to spawn and multiplexes the execution of all fibers within the main thread.

Fields
Fiber[] m_fibers
size_t m_pos
Methods
void start(void delegate() op)This creates a new `Fiber` for the supplied op and then starts the dispatcher.
void spawn(void delegate() op) nothrowThis created a new `Fiber` for the supplied op and adds it to the dispatch list.
void yield() nothrowIf the caller is a scheduled `Fiber`, this yields execution to another scheduled `Fiber`.
ThreadInfo thisInfo() @property ref nothrowReturns an appropriate `ThreadInfo` instance.
Condition newCondition(Mutex m) nothrowReturns a `Condition` analog that yields when wait or notify is called.
void create(void delegate() op) nothrowCreates a new `Fiber` which calls the given delegate.
void dispatch()
Nested Templates
InfoFiber`Fiber` which embeds a `ThreadInfo`
FiberCondition
private interfaceIsGenerator

Used to determine whether a Generator is running.

A Generator is a Fiber that periodically returns values of type T to the caller via yield. This is represented as an InputRange.

Fields
T * m_value
Methods
bool empty() @propertyReturns true if the generator is empty.
void popFront()Obtains the next value from the underlying function.
T front() @propertyReturns the most recently generated value by shallow copy.
T moveFront()Returns the most recently generated value without executing a copy contructor. Will not compile for element types defining a postblit, because `Generator` does not return by reference.
int opApply(scope int delegate(T) loopBody)
int opApply(scope int delegate(size_t, T) loopBody)
Constructors
this(void function() fn)Initializes a generator object which is associated with a static D function. The function will be called once to prepare the range for iteration.
this(void function() fn, size_t sz)Initializes a generator object which is associated with a static D function. The function will be called once to prepare the range for iteration.
this(void function() fn, size_t sz, size_t guardPageSize)Initializes a generator object which is associated with a static D function. The function will be called once to prepare the range for iteration.
this(void delegate() dg)Initializes a generator object which is associated with a dynamic D function. The function will be called once to prepare the range for iteration.
this(void delegate() dg, size_t sz)Initializes a generator object which is associated with a dynamic D function. The function will be called once to prepare the range for iteration.
this(void delegate() dg, size_t sz, size_t guardPageSize)Initializes a generator object which is associated with a dynamic D function. The function will be called once to prepare the range for iteration.
Fields
ListT m_localBox
ListT m_localPty
Mutex m_lock
Condition m_putMsg
Condition m_notFull
size_t m_putQueue
ListT m_sharedBox
ListT m_sharedPty
OnMaxFn m_onMaxMsgs
size_t m_localMsgs
size_t m_maxMsgs
bool m_closed
Methods
bool isClosed() @property @safe @nogc pure
void setMaxMsgs(size_t num, bool function(Tid) call) @safe @nogc pure
void put(ref Message msg)
bool get(T...)(scope T vals)
void close()
bool mboxFull() @safe @nogc pure nothrow
void updateMsgCount() @safe @nogc pure nothrow
bool isControlMsg(ref Message msg) @safe @nogc pure nothrow
bool isPriorityMsg(ref Message msg) @safe @nogc pure nothrow
bool isLinkDeadMsg(ref Message msg) @safe @nogc pure nothrow
Constructors
structList(T)
Fields
SpinLock sm_lock
Node * sm_head
Node * m_first
Node * m_last
size_t m_count
Methods
void put(T val)
void put(ref List!(T) rhs)
void removeAt(Range r)
size_t length() @property
void clear()
bool empty() @property
Node * newNode(T v)
void freeNode(Node * n)
void put(Node * n)
Nested Templates
Range
Node
SpinLock

Functions 32

fnbool hasLocalAliasing(Types...)()
fnvoid checkops(T...)(T ops)
fnThreadInfo thisInfo() @property ref nothrow
fnTid thisTid() @property @safeReturns: The `Tid` of the caller's thread.
fnTid ownerTid() @propertyReturn the `Tid` of the thread which spawned the caller's thread.
fnTid spawn(F, T...)(F fn, T args) if (isSpawnable!(F, T))Starts `fn(args)` in a new logical thread.
fnTid spawnLinked(F, T...)(F fn, T args) if (isSpawnable!(F, T))Starts `fn(args)` in a logical thread and will receive a `LinkTerminated` message when the operation terminates.
private fnTid _spawn(F, T...)(bool linked, F fn, T args) if (isSpawnable!(F, T))
fnvoid send(T...)(Tid tid, T vals)Places the values as a message at the back of tid's message queue.
fnvoid prioritySend(T...)(Tid tid, T vals)Places the values as a message on the front of tid's message queue.
private fnvoid _send(T...)(Tid tid, T vals)
private fnvoid _send(T...)(MsgType type, Tid tid, T vals)
fnvoid receive(T...)( T ops )Receives a message from another thread.
fnreceiveOnlyRet!(T) receiveOnly(T...)()Receives only messages with arguments of the specified types.
fnbool receiveTimeout(T...)(Duration duration, T ops)Receives a message from another thread and gives up if no match arrives within a specified duration.
fnbool onCrowdingBlock(Tid tid) @safe pure nothrow @nogc
fnbool onCrowdingThrow(Tid tid) @safe pure
fnbool onCrowdingIgnore(Tid tid) @safe pure nothrow @nogc
fnvoid setMaxMailboxSize(Tid tid, size_t messages, OnCrowding doThis) @safe pureSets a maximum mailbox size.
fnvoid setMaxMailboxSize(Tid tid, size_t messages, bool function(Tid) onCrowdingDoThis)Sets a maximum mailbox size.
private fnMutex registryLock() @property
private fnvoid unregisterMe(ref ThreadInfo me)
fnbool register(string name, Tid tid)Associates name with tid.
fnbool unregister(string name)Removes the registered name associated with a tid.
fnTid locate(string name)Gets the `Tid` associated with name.
fnvoid yield() nothrowIf the caller is a `Fiber` and is not a Generator, this function will call `scheduler.yield()` or `Fiber.yield()`, as appropriate.
fnvoid yield(T)(ref T value)Yields a value of type T to the caller of the currently executing generator.
fnvoid yield(T)(T value)ditto
private fnshared(Mutex) initOnceLock() @property
fnauto ref initOnce(alias var)(lazy typeof(var) init)Initializes var with the lazy init value in a thread-safe manner.
fnauto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex)Same as above, but takes a separate mutex instead of sharing one among all initOnce instances.
fnauto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex)ditto

Variables 3

varTid[string] tidByName
varstring[][Tid] namesByTid
varScheduler scheduler

Sets the Scheduler behavior within the program.

This variable sets the Scheduler behavior within this program. Typically, when setting a Scheduler, scheduler.start() should be called in main. This routine will not return until program execution is complete.

Templates 2

tmplisSpawnable(F, T...)
tmplreceiveOnlyRet(T...)