Savoga

Atomic


Atomic is to be used on an object to make sure read & write are indivisible (=> operations on that object are thread-safe). In other words, once a thread accesses the object, it prevents any other threads to modify it (they can still access it) before the first one finishes its operations. The other threads are not blocked, they rather keep trying until they succeed.

In the below script, atomic makes sure that t2 (resp. t1) is not modifying counter while t1 (resp. t2) is modifying it.


#include <atomic> 
#include <iostream> 
#include <thread> 

std::atomic<int> counter{0}; 
// int counter = 0; 

void increment() { 
	for (int i = 0; i < 1000; ++i) { 
	++counter; // atomic increment 
	} 
} 

int main() { 
	std::thread t1(increment); 
	std::thread t2(increment); 
	t1.join(); 
	t2.join(); 
	std::cout << "Counter: " << counter << '\n'; // should be 2000 
} 

Lock-free data structures rely on atomic operations and are especially suited for SPSC design (single-producer single-consumer). One writes at the tail, one reads at the head. Both progress independently.

mutex -> every push/pop needs to take a lock

lockfree structure -> no lock but atomic operations, producer/consumer never blocks each other