Search code examples
c++multithreadingc++11mutexstdatomic

When should you use std::atomic instead of std::mutex?


In the question How to use std::atomic<>, obviously we can just use std::mutex to keep thread safety. I want to know when to use which one.

struct A {
    std::atomic<int> x{0};
    void Add() {
        x++;
    }
    void Sub() {
        x--;
    }
};

vs.

std::mutex mtx;
struct A {
    int x = 0;
    void Add() {
        std::lock_guard<std::mutex> guard(mtx);
        x++;
    }
    void Sub() {
        std::lock_guard<std::mutex> guard(mtx);
        x--;
    }     
};

Solution

  • As a rule of thumb, use std::atomic for POD types where the underlying specialisation will be able to use something clever like a bus lock on the CPU (which will give you no more overhead than a pipeline dump), or even a spin lock. On some systems, an int might already be atomic, so std::atomic<int> will specialise out effectively to an int.

    Use std::mutex for non-POD types, bearing in mind that acquiring a mutex is at least an order of magnitude slower than a bus lock.

    If you're still unsure, measure the performance.