Какие знаешь Lock Guard в стандартной библиотеке
1️⃣ Как кратко ответить
В стандартной библиотеке C++ есть несколько типов Lock Guard: std::lock_guard, std::unique_lock и std::scoped_lock. std::lock_guard обеспечивает простую RAII-блокировку мьютекса, std::unique_lock предоставляет более гибкое управление блокировкой, включая возможность отложенной блокировки и разблокировки, а std::scoped_lock поддерживает одновременную блокировку нескольких мьютексов.
2️⃣ Подробное объяснение темы
В многопоточных приложениях важно правильно управлять доступом к общим ресурсам, чтобы избежать состояния гонки и других проблем синхронизации. Для этого используются мьютексы, которые позволяют блокировать доступ к ресурсу. Lock Guards в C++ помогают управлять мьютексами, обеспечивая автоматическое управление их блокировкой и разблокировкой.
std::lock_guard
std::lock_guard — это простой RAII-объект, который блокирует мьютекс при создании и автоматически разблокирует его при уничтожении. Это делает код более безопасным и защищает от забывания разблокировки мьютекса.
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx;
void print_message(const std::string& message) {
std::lock_guard<std::mutex> lock(mtx); // Блокирует мьютекс mtx
std::cout << message << std::endl; // Потокобезопасный вывод
} // Мьютекс автоматически разблокируется при выходе из области видимости
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::unique_lock
std::unique_lock предоставляет более гибкое управление мьютексом. Он позволяет отложить блокировку, разблокировать мьютекс до выхода из области видимости и повторно его заблокировать.
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx;
void print_message(const std::string& message) {
std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // Создает объект без блокировки
lock.lock(); // Явно блокирует мьютекс
std::cout << message << std::endl; // Потокобезопасный вывод
lock.unlock(); // Явно разблокирует мьютекс
} // Мьютекс не разблокируется автоматически, так как уже разблокирован
int main() {
std::thread t1(print_message, "Hello from thread 1");
std::thread t2(print_message, "Hello from thread 2");
t1.join();
t2.join();
return 0;
}
std::scoped_lock
std::scoped_lock используется для одновременной блокировки нескольких мьютексов. Это предотвращает взаимные блокировки (deadlocks), которые могут возникнуть при последовательной блокировке нескольких мьютексов.
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx1, mtx2;
void task1() {
std::scoped_lock lock(mtx1, mtx2); // Одновременная блокировка mtx1 и mtx2
std::cout << "Task 1 is running" << std::endl;
} // Мьютексы автоматически разблокируются при выходе из области видимости
void task2() {
std::scoped_lock lock(mtx1, mtx2); // Одновременная блокировка mtx1 и mtx2
std::cout << "Task 2 is running" << std::endl;
} // Мьютексы автоматически разблокируются при выходе из области видимости
int main() {
std::thread t1(task1);
std::thread t2(task2);
t1.join();
t2.join();
return 0;
}
Lock Guards в C++ обеспечивают безопасное и эффективное управление мьютексами, минимизируя риск ошибок синхронизации и упрощая код.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться