РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
781 of 815 menu

Класс recursive_mutex

Класс recursive_mutex представляет собой рекурсивный мьютекс. В отличие от обычного mutex, он позволяет одному и тому же потоку захватывать блокировку несколько раз подряд. Каждый успешный вызов lock или try_lock увеличивает внутренний счётчик владения, а каждый вызов unlock уменьшает его. Поток освобождает мьютекс только тогда, когда счётчик достигнет нуля.

Это удобно в рекурсивных функциях, когда одна и та же функция, захватившая мьютекс, вызывает себя или другую функцию, которая снова пытается захватить тот же мьютекс. Обычный mutex в такой ситуации приведёт к взаимоблокировке, а recursive_mutex - нет. У класса нет конструктора с параметрами, он создаётся по умолчанию.

Синтаксис

#include <mutex> std::recursive_mutex mtx; mtx.lock(); mtx.try_lock(); mtx.unlock();

Пример

Давайте захватим рекурсивный мьютекс несколько раз в одном потоке и убедимся, что взаимоблокировки не происходит:

#include <iostream> #include <mutex> using namespace std; int main() { recursive_mutex mtx; mtx.lock(); cout << "first lock" << endl; mtx.lock(); cout << "second lock" << endl; mtx.unlock(); cout << "first unlock" << endl; mtx.unlock(); cout << "second unlock" << endl; return 0; }

Результат выполнения кода:

"first lock" "second lock" "first unlock" "second unlock"

Пример

Давайте напишем рекурсивную функцию, которая захватывает recursive_mutex на каждом уровне рекурсии и считает сумму чисел от 1 до 5:

#include <iostream> #include <mutex> using namespace std; recursive_mutex mtx; int sum(int n) { mtx.lock(); if (n <= 0) { mtx.unlock(); return 0; } int res = n + sum(n - 1); mtx.unlock(); return res; } int main() { cout << sum(5) << endl; return 0; }

Результат выполнения кода:

15

Пример

Давайте проверим работу метода try_lock при повторном захвате мьютекса тем же потоком:

#include <iostream> #include <mutex> using namespace std; int main() { recursive_mutex mtx; mtx.lock(); if (mtx.try_lock()) { cout << "try_lock success" << endl; mtx.unlock(); } else { cout << "try_lock failed" << endl; } mtx.unlock(); return 0; }

Результат выполнения кода:

"try_lock success"

Смотрите также

  • класс mutex,
    который представляет обычный нерекурсивный мьютекс
  • метод lock,
    который захватывает мьютекс
  • метод try_lock,
    который пытается захватить мьютекс без блокировки
  • метод unlock,
    который освобождает мьютекс
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить