← Назад ко всем вопросам

Какие знаешь 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++ обеспечивают безопасное и эффективное управление мьютексами, минимизируя риск ошибок синхронизации и упрощая код.

Тема: Многопоточность / Синхронизация
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки