Atomic Counters in Elixir
In Elixir, we can use the :atomics
module to work with atomic counters. Here’s how we can implement atomic counters:
In this Elixir implementation:
We use
:atomics.new/2
to create a new atomic counter. The first argument1
specifies that we want a single counter, andsigned: false
indicates that it’s an unsigned integer.Instead of goroutines, we use Elixir’s
Task
module to create concurrent tasks.We use
:atomics.add/3
to atomically increment the counter. The first argument is the atomic reference, the second is the index (1 in this case as we only have one counter), and the third is the value to add.We use
Task.await_many/1
to wait for all tasks to complete, which is similar toWaitGroup.Wait()
in the original example.Finally, we use
:atomics.get/2
to safely read the final value of the counter.
To run this program:
We expect to get exactly 50,000 operations. If we had used a non-atomic integer and incremented it with regular addition, we’d likely get a different number, changing between runs, because the tasks would interfere with each other.
Elixir’s :atomics
module provides thread-safe operations on individual numbers, making it suitable for scenarios where you need to share counters or flags between multiple processes without explicit locking.