Stateful Goroutines in Nim
This example demonstrates how to use channels and threads (Nim’s equivalent to goroutines) to manage state in a concurrent program. The approach aligns with the idea of sharing memory by communicating, where each piece of data is owned by exactly one thread.
In this example, our state is owned by a single thread. This guarantees that the data is never corrupted with concurrent access. To read or write that state, other threads send messages to the owning thread and receive corresponding replies. The ReadOp
and WriteOp
objects encapsulate these requests and provide a way for the owning thread to respond.
The main function starts by setting up channels for reads and writes, and atomic counters for operation counts. It then spawns a thread that owns the state (a Table
in Nim, equivalent to a map in other languages). This thread repeatedly selects on the reads
and writes
channels, responding to requests as they arrive.
Next, it starts 100 threads to issue reads and 10 threads to issue writes. Each read or write operation constructs the appropriate operation object, sends it over the corresponding channel, and then receives the result.
After letting the threads work for a second, the program captures and reports the final operation counts.
To run this program:
For this particular case, the thread-based approach is more involved than a mutex-based one. However, it can be useful in certain scenarios, especially when dealing with multiple channels or when managing multiple mutexes would be error-prone. Choose the approach that feels most natural and helps you understand the correctness of your program more easily.