std::mutex
Определено в заголовочном файле <mutex>
|
||
class mutex; |
(начиная с C++11) | |
Класс mutex
является примитивом синхронизации, который может использоваться для защиты разделяемых данных от одновременного доступа нескольких потоков.
mutex
предлагает эксклюзивную, нерекурсивную семантику владения:
- Вызывающий поток владеет
mutex
со времени успешного вызоваlock
илиtry_lock
, и до момента вызоваunlock
. - Когда поток владеет
mutex
, все другие потоки будут заблокированы (для вызововlock
) или получат возвращаемое значение false (дляtry_lock
), если они попытаются получить права владенияmutex
. - Вызывающий поток не должен владеть
mutex
до вызоваlock
илиtry_lock
.
Поведение программы не определено, если mutex
уничтожается, когда он всё ещё принадлежит каким-либо потокам, или поток завершается, пока владеет mutex
. Класс mutex
соответствует всем требованиям Mutex и StandardLayoutType.
Класс mutex
является некопируемым и неперемещаемым.
Содержание |
[править] Типы-элементы
Тип-элемент | Определение |
native_handle_type (не всегда присутствует)
|
определяется реализацией |
[править] Функции-элементы
создаёт мьютекс (public функция-элемент) | |
уничтожает мьютекс (public функция-элемент) | |
operator= [удалено] |
копирующее присваивание не возможно (public функция-элемент) |
Блокировка | |
блокирует мьютекс, блокируется, если мьютекс недоступен (public функция-элемент) | |
пытается заблокировать мьютекс, возвращается, если мьютекс недоступен (public функция-элемент) | |
разблокирует мьютекс (public функция-элемент) | |
Встроенный дескриптор | |
возвращает базовый объект-дескриптор, определяемый реализацией (public функция-элемент) |
[править] Примечание
К std::mutex
обычно не обращаются напрямую: std::unique_lock, std::lock_guard или std::scoped_lock (начиная с C++17) управляют блокировкой более безопасным способом.
[править] Пример
В этом примере показано, как mutex
можно использовать для защиты std::map, совместно используемого двумя потоками.
#include <iostream> #include <map> #include <string> #include <chrono> #include <thread> #include <mutex> std::map<std::string, std::string> g_pages; std::mutex g_pages_mutex; void save_page(const std::string &url) { // имитация получение длинной страницы std::this_thread::sleep_for(std::chrono::seconds(2)); std::string result = "случайное содержимое"; std::lock_guard<std::mutex> guard(g_pages_mutex); g_pages[url] = result; } int main() { std::thread t1(save_page, "http://foo"); std::thread t2(save_page, "http://bar"); t1.join(); t2.join(); // безопасный доступ к g_pages без блокировки, так как потоки объединены for (const auto &pair : g_pages) { std::cout << pair.first << " => " << pair.second << '\n'; } }
Вывод:
http://bar => случайное содержимое http://foo => случайное содержимое
[править] Смотрите также
(C++11) |
предоставляет возможность взаимного исключения, которое может быть рекурсивно заблокировано одним и тем же потоком (класс) |
(C++11) |
реализует обёртку владения мьютексом строго в области видимости (шаблон класса) |
(C++11) |
реализует перемещаемую оболочку владения мьютексом (шаблон класса) |
(C++17) |
обёртка RAII для предотвращения взаимоблокировок для нескольких мьютексов (шаблон класса) |
(C++11) |
предоставляет условную переменную, связанную с std::unique_lock (класс) |