Назад к вопросам
Middle
124
questionbank

Какие виды мьютексов существуют в стандартной библиотеке C++?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

В стандартной библиотеке C++ (начиная с C++11) доступны следующие виды мьютексов:

  1. std::mutex: Базовый, нерекурсивный мьютекс. Может быть заблокирован только один раз одним потоком. При попытке повторной блокировки из того же потока возникает неопределенное поведение.
  2. std::recursive_mutex: Рекурсивный мьютекс. Поток может блокировать его несколько раз. Для каждого lock() требуется соответствующий unlock().
  3. std::timed_mutex: Нерекурсивный мьютекс с возможностью попытки блокировки в течение определенного времени (try_lock_for, try_lock_until).
  4. std::recursive_timed_mutex: Рекурсивный мьютекс с возможностью попытки блокировки в течение определенного времени.

Кроме того, для реализации общей блокировки (множество потоков могут одновременно читать, но только один может писать) существует:

  1. std::shared_mutex (C++17): Обеспечивает два уровня блокировки: совместную (для чтения, несколько потоков) и эксклюзивную (для записи, один поток).
  2. std::shared_timed_mutex (C++14): Аналогичен std::shared_mutex, но с возможностью попытки блокировки в течение определенного времени.

Наиболее часто используемым является std::mutex. std::recursive_mutex следует использовать осторожно, так как он может скрывать логические ошибки. В C++14/17 для многих сценариев чтения/записи предпочтительнее использовать std::shared_mutex или std::shared_timed_mutex.

#include <mutex>
#include <shared_mutex> // C++17 for std::shared_mutex

// Пример использования std::mutex
std::mutex m;

void critical_section() {
    m.lock();       // Блокировка
    // Критическая секция
    m.unlock();     // Разблокировка
}

// Пример использования std::lock_guard для автоматической разблокировки
std::mutex m2;

void critical_section_guarded() {
    std::lock_guard<std::mutex> lock(m2); // Блокировка при создании, разблокировка при выходе из области видимости
    // Критическая секция
}

// Пример использования std::shared_mutex для чтения
std::shared_mutex shared_m;

void read_data() {
    shared_m.lock_shared(); // Блокировка для чтения (несколько потоков могут войти)
    // Чтение данных
    shared_m.unlock_shared(); // Разблокировка для чтения
}

void write_data() {
    shared_m.lock();        // Блокировка для записи (только один поток может войти)
    // Запись данных
    shared_m.unlock();      // Разблокировка для записи
}