Message Passing

Instead of dealing with threads and doing synchronization yourself D allows to use message passing as a means to leverage the power of multiple cores. Threads communicate with messages - which are arbitrary values - to distribute work and synchronize themselves. They don't share data by design which avoids the common problems of multi-threading.

All functions that implement message passing in D can be found in the std.concurrency module. spawn creates a new thread based on a user-defined function:

auto threadId = spawn(&foo, thisTid);

thisTid is a std.concurrency built-in and references the current thread which is needed for message passing. spawn takes a function as first parameter and additional parameters to that function as arguments.

void foo(Tid parentTid) {
    receive(
      (int i) { writeln("An ", i, " was sent!"); }
    );
    
    send(parentTid, "Done");
}

The receive function is like a switch-case and dispatches the values it receives from other threads to the passed delegates - depending on the received value's type.

To send a message to a specific thread use the function send and its id:

send(threadId, 42);

receiveOnly can be used to just receive a specified type:

string text = receiveOnly!string();
assert(text == "Done");

The receive family functions block until something has been sent to the thread's mailbox.

In-depth

rdmd playground.d