Message Passing

Instead of dealing with threads and doing synchronization yourself, D allows you to use message passing to take advantage 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 D's message passing functions 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.

You can send a message to a specific thread using the send function and the target thread's id:

send(threadId, 42);

receiveOnly can be used to ensure that only a specified type is received:

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