std::lock in C++std::lock is a function template in C++ that provides a way to lock multiple mutex objects simultaneously. It's designed to prevent deadlocks when locking multiple mutexes and is part of the C++ Standard Library's concurrency support.
std::mutex<mutex> header#include <iostream>
#include <thread>
#include <mutex>
std::mutex mutex1, mutex2;
void task_a() {
std::lock(mutex1, mutex2);
std::cout << "Task A acquired both locks\n";
mutex1.unlock();
mutex2.unlock();
}
void task_b() {
std::lock(mutex2, mutex1); // Note the different order
std::cout << "Task B acquired both locks\n";
mutex2.unlock();
mutex1.unlock();
}
int main() {
std::thread t1(task_a);
std::thread t2(task_b);
t1.join();
t2.join();
return 0;
}
std::lock is used to lock both mutexes simultaneously in each task.std::lock doesn't matter; it prevents deadlocks.std::lock avoids the circular wait problem.std::lock with std::unique_lock#include <iostream>
#include <thread>
#include <mutex>
class Account {
public:
Account(int balance) : balance_(balance) {}
void transfer(Account& to, int amount) {
std::unique_lock<std::mutex> lock_from(mutex_, std::defer_lock);
std::unique_lock<std::mutex> lock_to(to.mutex_, std::defer_lock);
std::lock(lock_from, lock_to);
if (balance_ >= amount) {
balance_ -= amount;
to.balance_ += amount;
std::cout << "Transfer successful\n";
} else {
std::cout << "Insufficient funds\n";
}
}
private:
int balance_;
std::mutex mutex_;
};
int main() {
Account acc1(1000);
Account acc2(500);
std::thread t1(&Account::transfer, &acc1, std::ref(acc2), 300);
std::thread t2(&Account::transfer, &acc2, std::ref(acc1), 200);
t1.join();
t2.join();
return 0;
}
std::unique_lock is used with std::defer_lock to create lockable objects without immediately locking.std::lock is then used to lock both unique_lock objects simultaneously.std::lock for deadlock prevention.#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx1, mtx2, mtx3, mtx4;
void complex_operation(int id) {
std::vector<std::mutex*> mutexes = {&mtx1, &mtx2, &mtx3, &mtx4};
// Shuffle the order of mutexes to simulate different locking orders
if (id % 2 == 0) {
std::swap(mutexes[0], mutexes[3]);
std::swap(mutexes[1], mutexes[2]);
}
std::lock(*mutexes[0], *mutexes[1], *mutexes[2], *mutexes[3]);
std::cout << "Thread " << id << " acquired all locks\n";
// Unlock in reverse order
mutexes[3]->unlock();
mutexes[2]->unlock();
mutexes[1]->unlock();
mutexes[0]->unlock();
}
int main() {
std::vector<std::thread> threads;
for (int i = 0; i < 4; ++i) {
threads.emplace_back(complex_operation, i);
}
for (auto& t : threads) {
t.join();
}
return 0;
}
std::lock can take any number of mutex arguments, preventing deadlocks regardless of the order.Exception Safety: If an exception is thrown while std::lock is acquiring locks, it ensures that any already acquired locks are released.
Performance: While std::lock prevents deadlocks, it may introduce some overhead compared to manually ordering locks.
Alternatives: For simpler cases, consider using std::scoped_lock (C++17) which provides similar functionality with RAII semantics.
Unlock Order: When manually unlocking, it's good practice to unlock in the reverse order of acquisition, though not strictly necessary with std::lock.
Deadlock Prevention: std::lock uses an unspecified algorithm to prevent deadlocks, which may involve a back-off and retry strategy.
std::lock is a powerful tool in C++ for safely acquiring multiple locks simultaneously, preventing deadlocks in multi-threaded programs. It's particularly useful in complex scenarios where lock ordering is difficult to manage manually or where the lock order may vary. While it provides strong guarantees against deadlocks, it should be used judiciously, considering performance implications in high-contention scenarios. For most cases, especially in modern C++, wrapper classes like std::unique_lock or std::scoped_lock (C++17) provide a more convenient and exception-safe way to use std::lock's functionality. Understanding and correctly using std::lock is crucial for writing robust, deadlock-free multi-threaded C++ programs.
[1] https://cplusplus.com/reference/mutex/lock/ [2] https://web.stanford.edu/~ouster/cs111-spring21/lectures/locks/ [3] https://en.cppreference.com/w/cpp/thread/mutex/lock [4] https://stackoverflow.com/questions/18520983/is-stdlock-ill-defined-unimplementable-or-useless [5] https://www.geeksforgeeks.org/std-mutex-in-cpp/
Previous Page | Course Schedule | Course Content