Atomic Counters in D Programming Language
Our primary mechanism for managing state in D is through message passing and synchronization primitives. However, there are other options for managing state as well. In this example, we’ll look at using the core.atomic module for atomic counters accessed by multiple threads.
import std.stdio;
import std.parallelism;
import core.atomic;
import core.thread;
void main()
{
// We'll use an atomic integer to represent our (always-positive) counter.
shared long ops;
// We'll start 50 tasks that each increment the counter exactly 1000 times.
auto pool = new TaskPool(50);
scope(exit) pool.finish();
foreach (_; 0..50)
{
pool.put(task({
for (int c = 0; c < 1000; c++)
{
// To atomically increment the counter we use atomicOp!"+="
atomicOp!"+="(ops, 1);
}
}));
}
// Wait until all the tasks are done.
pool.finish(true);
// Here no threads are writing to 'ops', but it's safe to atomically
// read a value even while other threads might be updating it.
writeln("ops: ", atomicLoad(ops));
}We expect to get exactly 50,000 operations. Had we used a non-atomic integer and incremented it with ops++, we’d likely get a different number, changing between runs, because the threads would interfere with each other. Moreover, we might encounter race conditions.
To run the program:
$ dmd -run atomic_counters.d
ops: 50000In this D version:
We use
shared long opsto declare a shared variable that can be safely accessed from multiple threads.Instead of goroutines, we use D’s
std.parallelismmodule to create a thread pool and spawn tasks.The
atomicOp!"+="function is used to atomically increment the counter, which is equivalent to theAddmethod in Go.We use
atomicLoadto safely read the final value of the counter, which is similar to theLoadmethod in Go.The
TaskPooland itsfinishmethod are used to manage and wait for all tasks to complete, serving a similar purpose to Go’sWaitGroup.
This example demonstrates how to use atomic operations in D to safely manage a counter across multiple threads, achieving the same goal as the original Go program.