Channel Synchronization in D Programming Language
This example demonstrates how to use channels to synchronize execution across threads. We’ll use a blocking receive to wait for a thread to finish. When waiting for multiple threads to finish, you may prefer to use a core.sync.Barrier
instead.
import std.stdio;
import core.thread;
import core.time;
// This is the function we'll run in a thread. The
// `done` channel will be used to notify another
// thread that this function's work is done.
void worker(shared bool* done)
{
write("working...");
Thread.sleep(dur!"seconds"(1));
writeln("done");
// Set the flag to notify that we're done.
*done = true;
}
void main()
{
// Create a shared boolean flag for synchronization
shared bool done = false;
// Start a worker thread, giving it a pointer to the flag
auto workerThread = new Thread(() => worker(&done));
workerThread.start();
// Block until we receive a notification from the
// worker that it's done
while (!done) {
Thread.yield();
}
}
To run the program:
$ dmd -run channel-synchronization.d
working...done
If you removed the while (!done)
loop from this program, the program would exit before the worker
even started.
In D, we use shared memory and a boolean flag for synchronization instead of channels. The shared
keyword ensures proper synchronization between threads. We use a while loop with Thread.yield()
to efficiently wait for the worker thread to complete its task.
D’s approach to concurrency is different from some other languages, but it provides powerful tools for managing shared state and synchronization between threads.