std::atomic


Keyword: std::atomic

std::atomic is a template class in the C++ Standard Library that provides a way to perform atomic operations on variables. Atomic operations are those that are performed without the possibility of interruption by other threads, making them essential for writing safe and efficient multi-threaded programs.

Key Concepts of std::atomic

Here's a simple example demonstrating the use of std::atomic:

Example 1: Basic Usage

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

std::atomic<int> counter(0);  // Atomic integer

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 << "Final counter value: " << counter << std::endl;  // Should be 2000

    return 0;
}

Explanation:

Atomic Operations

Example2: compare-and-swap

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

std::atomic<int> counter(0);

void increment_if_zero() {
    int expected = 0;
    if (counter.compare_exchange_strong(expected, 100)) {
        std::cout << "Counter was zero, updated to 100" << std::endl;
    } else {
        std::cout << "Counter was not zero, value is " << counter.load() << std::endl;
    }
}

int main() {
    std::thread t1(increment_if_zero);
    std::thread t2(increment_if_zero);

    t1.join();
    t2.join();

    std::cout << "Final counter value: " << counter << std::endl;

    return 0;
}

Explanation:

Example3: Memory Ordering

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

std::atomic<int> data(0);
std::atomic<bool> ready(false);

void producer() {
    data.store(42, std::memory_order_relaxed);
    ready.store(true, std::memory_order_release);  // Release: Ensures data is visible
}

void consumer() {
    while (!ready.load(std::memory_order_acquire));  // Acquire: Waits for release
    std::cout << "Data: " << data.load(std::memory_order_relaxed) << std::endl;
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);

    t1.join();
    t2.join();

    return 0;
}

Explanation

Common Use Cases

Summary

Using std::atomic allows you to write efficient and correct multi-threaded programs by avoiding the complexities of manual synchronization with mutexes.

Previous Page | Course Schedule | Course Content