Daily bit(e) C++. std::mutex

Добавлено 24 августа 2023 в 08:07

Daily bit(e) C++ #12, блокировка взаимного исключения std::mutex

Daily bit(e) C++. 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.

Теги

C++ / CppDaily bit(e) C++Mutex / МьютексRAII / Resource Acquisition Is Initialization / Получение ресурса есть инициализацияstd::mutexSTL / Standard Template Library / Стандартная библиотека шаблоновМногопоточностьПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.