Sobes.tech
Middle+

How does the atomic locking mechanism of two mutexes work?

sobes.tech AI

Answer from AI

The std::lock function is used for correct atomic locking of two mutexes. It guarantees that either both mutexes are successfully locked or none of them are.

The algorithm of std::lock is as follows:

  1. Attempts to lock the first mutex.
  2. If successful, attempts to lock the second mutex.
  3. If the second mutex is also successfully locked, both mutexes remain locked.
  4. If locking the second mutex fails (for example, it is already locked by another thread), the lock on the first mutex is released, and the function waits until both mutexes are free, then retries.

This prevents deadlocks that could occur with manual sequential locking:

// Example of error:
std::mutex m1, m2;

void func1() {
    m1.lock();
    m2.lock(); // Can cause deadlock if another thread has already locked m2 and is waiting for m1
    // ... work with protected resources
    m2.unlock();
    m1.unlock();
}

void func2() {
    m2.lock();
    m1.lock(); // Can cause deadlock
    // ... work with protected resources
    m1.unlock();
    m2.unlock();
}

Using std::lock:

#include <mutex>

std::mutex m1, m2;

void safe_func() {
    std::lock(m1, m2); // Atomic locking of both mutexes
    // ... work with protected resources
    // Unlock mutexes in reverse order or using lock_guard
    m2.unlock();
    m1.unlock();
}

A more preferred way using std::unique_lock and std::adopt_lock:

#include <mutex>
#include <memory>

std::mutex m1, m2;

void safe_func_with_guards() {
    std::lock(m1, m2); // Atomic lock
    std::unique_lock<std::mutex> lock1(m1, std::adopt_lock); // Associate lock_guard with already locked mutex
    std::unique_lock<std::mutex> lock2(m2, std::adopt_lock); // Associate lock_guard with already locked mutex
    // Now mutexes will be automatically unlocked when leaving scope
    // ... work with protected resources
}

Using std::lock with std::unique_lock is considered best practice, as it guarantees proper release of mutexes even in case of exceptions.