Класс lock_guard
Класс lock_guard представляет собой удобный
RAII-обёртку над мьютексом. При создании объекта
lock_guard мьютекс автоматически блокируется,
а при разрушении объекта (выходе из области
видимости) - автоматически разблокируется.
В конструктор передаётся ссылка на мьютекс,
который нужно захватить. Класс не позволяет
вручную разблокировать мьютекс или копировать
себя - это гарантирует, что блокировка всегда
будет снята корректно, даже при выбросе
исключения.
Для использования класса необходимо подключить
заголовочный файл <mutex>.
Синтаксис
std::lock_guard<Mutex> guard(mutex);
Пример
Давайте захватим мьютекс с помощью
lock_guard и выведем сообщение в
защищённой секции:
#include <iostream>
#include <mutex>
using namespace std;
int main()
{
mutex mtx;
{
lock_guard<mutex> guard(mtx);
cout << "Locked section" << endl;
}
cout << "Unlocked section" << endl;
return 0;
}
Результат выполнения кода:
"Locked section"
"Unlocked section"
Пример
Давайте используем lock_guard вместе
с двумя потоками, чтобы защитить общий
счётчик от гонки данных:
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex mtx;
int counter = 0;
void increment(int n)
{
for (int i = 0; i < n; i++)
{
lock_guard<mutex> guard(mtx);
counter++;
}
}
int main()
{
thread t1(increment, 1000);
thread t2(increment, 1000);
t1.join();
t2.join();
cout << counter << endl;
return 0;
}
Результат выполнения кода:
2000
Пример
Давайте убедимся, что блокировка снимается автоматически даже при выбросе исключения внутри защищённой секции:
#include <iostream>
#include <mutex>
#include <stdexcept>
using namespace std;
mutex mtx;
int main()
{
try
{
lock_guard<mutex> guard(mtx);
cout << "Inside guard" << endl;
throw runtime_error("error");
}
catch (const exception& e)
{
cout << "Caught: " << e.what() << endl;
}
mtx.lock();
cout << "Mutex is free" << endl;
mtx.unlock();
return 0;
}
Результат выполнения кода:
"Inside guard"
"Caught: error"
"Mutex is free"
Смотрите также
-
класс
mutex,
который представляет собой базовый мьютекс -
метод
lock,
который вручную блокирует мьютекс -
метод
unlock,
который вручную разблокирует мьютекс -
класс
unique_lock,
который предоставляет более гибкое управление блокировкой