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

Класс shared_mutex

Класс shared_mutex представляет собой мьютекс, который позволяет нескольким потокам одновременно получать доступ к данным для чтения, но только одному потоку разрешает изменять эти данные. Такой режим работы называется разделяемым доступом (shared access). Класс shared_mutex находится в заголовочном файле <shared_mutex> и является частью пространства имен std.

Класс предоставляет два типа блокировок: эксклюзивную (исключительную) и разделяемую (общую). Эксклюзивная блокировка выполняется через методы lock, try_lock и unlock - при ее захвате никакой другой поток не может получить доступ к данным. Разделяемая блокировка выполняется через методы lock_shared, try_lock_shared и unlock_shared - при ее захвате другие потоки также могут захватить разделяемую блокировку, но не могут захватить эксклюзивную.

Синтаксис

#include <shared_mutex> std::shared_mutex mtx; // эксклюзивная блокировка mtx.lock(); mtx.unlock(); // разделяемая блокировка mtx.lock_shared(); mtx.unlock_shared();

Пример

Давайте рассмотрим пример, в котором 3 потока одновременно читают значение переменной, а один поток изменяет его. Для чтения используется разделяемая блокировка, для записи - эксклюзивная:

#include <iostream> #include <shared_mutex> #include <thread> #include <vector> using namespace std; shared_mutex mtx; int value = 0; void reader(int id) { shared_lock<shared_mutex> lock(mtx); cout << "reader " << id << ": " << value << endl; } void writer(int newValue) { unique_lock<shared_mutex> lock(mtx); value = newValue; cout << "writer: " << value << endl; } int main() { vector<thread> threads; threads.push_back(thread(reader, 1)); threads.push_back(thread(reader, 2)); threads.push_back(thread(writer, 5)); threads.push_back(thread(reader, 3)); for (auto& t : threads) { t.join(); } return 0; }

Результат выполнения кода (порядок строк может отличаться из-за многопоточности):

"reader 1: 0" "reader 2: 0" "writer: 5" "reader 3: 5"

Пример

Давайте используем метод try_lock_shared, чтобы попытаться захватить разделяемую блокировку без ожидания. Если блокировка уже захвачена другим потоком эксклюзивно, метод вернет false:

#include <iostream> #include <shared_mutex> #include <thread> using namespace std; shared_mutex mtx; int value = 0; void writer() { unique_lock<shared_mutex> lock(mtx); value = 10; cout << "writer: " << value << endl; this_thread::sleep_for(chrono::milliseconds(100)); } void reader() { if (mtx.try_lock_shared()) { cout << "reader: " << value << endl; mtx.unlock_shared(); } else { cout << "reader: lock failed" << endl; } } int main() { thread t1(writer); this_thread::sleep_for(chrono::milliseconds(10)); thread t2(reader); t1.join(); t2.join(); return 0; }

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

"writer: 10" "reader: lock failed"

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

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