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 (класс) |