Daily bit(e) C++. std::mutex
Daily bit(e) C++ #12, блокировка взаимного исключения std::mutex
std::mutex
(блокировка взаимного исключения) – примитив синхронизации, позволяющий удерживать блокировку только одному владельцу. Последующая попытка получения блокировки будет заблокирована до тех пор, пока предыдущий владелец блокировки не освободит ее.
Хотя мьютекс можно заблокировать и разблокировать вручную, вместо этого желательно использовать std::unique_lock
на основе RAII, который всегда будет правильно освобождать удерживаемую блокировку, предотвращая случайные взаимные блокировки.
#include <mutex>
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
using namespace std::chrono_literals;
struct Shared
{
int value;
std::mutex mux;
};
Shared shared{0,{}};
auto t1 = std::jthread([&shared]
{
std::this_thread::sleep_for(200ms); // только для демонстрации
for (int i = 0; i < 10; i++)
{
std::this_thread::yield(); // только для демонстрации
{
// обеспечиваем блокировку
std::unique_lock lock(shared.mux);
// изменяем общее состояние
shared.value += 10;
} // мьютекс разблокируется при утичтожении std::unique_lock
std::this_thread::sleep_for(100ms); // только для демонстрации
}
});
auto t2 = std::jthread([&shared]
{
std::this_thread::sleep_for(200ms); // только для демонстрации
for (int i = 0; i < 10; i++)
{
std::this_thread::yield(); // только для демонстрации
{
// обеспечиваем блокировку
std::unique_lock lock(shared.mux);
// изменяем общее состояние
shared.value += 1;
} // мьютекс разблокируется при утичтожении std::unique_lock
std::this_thread::sleep_for(100ms); // только для демонстрации
}
});
auto observer = std::jthread([&shared]
{
while (true)
{
std::this_thread::yield(); // только для демонстрации
{
// обеспечиваем блокировку
std::unique_lock lock(shared.mux);
// читаем общее состояние
std::cout << shared.value << std::endl;
if (shared.value == 110)
break;
} // мьютекс разблокируется при утичтожении std::unique_lock
std::this_thread::sleep_for(100ms); // только для демонстрации
}
});
}
Открыть пример на Compiler Explorer.