Какие знаешь виды мьютексов из стандартной библиотеки
1️⃣ Как кратко ответить
В стандартной библиотеке C++ есть несколько видов мьютексов: std::mutex, std::timed_mutex, std::recursive_mutex, std::recursive_timed_mutex, std::shared_mutex и std::shared_timed_mutex. Каждый из них предоставляет различные возможности для управления доступом к общим ресурсам в многопоточных приложениях.
2️⃣ Подробное объяснение темы
Мьютексы (mutexes) — это механизмы синхронизации, которые используются для предотвращения одновременного доступа к общим ресурсам в многопоточных приложениях. Они помогают избежать состояния гонки, когда несколько потоков пытаются изменить данные одновременно, что может привести к непредсказуемым результатам.
В стандартной библиотеке C++ есть несколько видов мьютексов, каждый из которых имеет свои особенности и предназначение:
-
std::mutex:- Это базовый мьютекс, который предоставляет простейший механизм блокировки. Он позволяет одному потоку захватить мьютекс, в то время как другие потоки будут заблокированы до тех пор, пока мьютекс не будет освобожден.
- Пример использования:
В этом примере#include <iostream> #include <thread> #include <mutex> std::mutex mtx; void print_message(const std::string& message) { mtx.lock(); // Захватываем мьютекс std::cout << message << std::endl; mtx.unlock(); // Освобождаем мьютекс } int main() { std::thread t1(print_message, "Hello from thread 1"); std::thread t2(print_message, "Hello from thread 2"); t1.join(); t2.join(); return 0; }std::mutexиспользуется для синхронизации доступа кstd::cout.
-
std::timed_mutex:- Это расширение
std::mutex, которое позволяет попытаться захватить мьютекс в течение определенного времени. Если мьютекс не может быть захвачен в течение этого времени, поток может продолжить выполнение. - Пример использования:
Здесь#include <iostream> #include <thread> #include <mutex> #include <chrono> std::timed_mutex tmtx; void try_lock_for_example() { if (tmtx.try_lock_for(std::chrono::milliseconds(100))) { std::cout << "Lock acquired" << std::endl; tmtx.unlock(); } else { std::cout << "Failed to acquire lock" << std::endl; } } int main() { std::thread t1(try_lock_for_example); std::thread t2(try_lock_for_example); t1.join(); t2.join(); return 0; }try_lock_forпытается захватить мьютекс в течение 100 миллисекунд.
- Это расширение
-
std::recursive_mutex:- Этот мьютекс позволяет одному и тому же потоку захватывать мьютекс несколько раз без блокировки. Это полезно в случаях, когда функция, захватывающая мьютекс, может быть вызвана рекурсивно.
- Пример использования:
В этом примере#include <iostream> #include <thread> #include <mutex> std::recursive_mutex rmtx; void recursive_function(int count) { if (count <= 0) return; rmtx.lock(); std::cout << "Recursion level: " << count << std::endl; recursive_function(count - 1); rmtx.unlock(); } int main() { std::thread t1(recursive_function, 3); t1.join(); return 0; }std::recursive_mutexпозволяет функцииrecursive_functionзахватывать мьютекс несколько раз.
-
std::recursive_timed_mutex:- Это комбинация
std::recursive_mutexиstd::timed_mutex, позволяющая рекурсивные захваты с возможностью установки тайм-аута. - Пример использования аналогичен
std::timed_mutex, но с возможностью рекурсивного захвата.
- Это комбинация
-
std::shared_mutex:- Этот мьютекс позволяет нескольким потокам одновременно читать данные, но только одному потоку записывать. Это полезно для оптимизации производительности, когда чтение данных происходит чаще, чем запись.
- Пример использования:
В этом примере#include <iostream> #include <thread> #include <shared_mutex> std::shared_mutex smtx; int shared_data = 0; void read_data() { smtx.lock_shared(); std::cout << "Read data: " << shared_data << std::endl; smtx.unlock_shared(); } void write_data(int value) { smtx.lock(); shared_data = value; std::cout << "Wrote data: " << shared_data << std::endl; smtx.unlock(); } int main() { std::thread t1(read_data); std::thread t2(write_data, 42); t1.join(); t2.join(); return 0; }std::shared_mutexиспользуется для разделения доступа кshared_data.
-
std::shared_timed_mutex:- Это расширение
std::shared_mutex, которое добавляет возможность установки тайм-аута для захвата мьютекса. - Пример использования аналогичен
std::shared_mutex, но с возможностью использования методовtry_lock_forиtry_lock_until.
- Это расширение
Каждый из этих мьютексов предоставляет различные возможности для управления доступом к общим ресурсам, и выбор конкретного типа мьютекса зависит от требований вашего приложения.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться