std::mutex
来自cppreference.com
<tbody>
</tbody>
| 在标头 <mutex> 定义
|
||
class mutex; |
(C++11 起) | |
mutex 类是能用于保护共享数据免受从多个线程同时访问的同步原语。
mutex 提供排他性非递归所有权语义:
- 调用方线程从它成功调用
lock或try_lock开始,到它调用unlock为止占有mutex。 - 线程占有
mutex时,其他线程如果试图要求mutex的所有权,那么就会阻塞(对于lock的调用)或收到false返回值(对于try_lock)。 - 调用方线程在调用
lock或try_lock前必须不占有mutex。
如果 mutex 在仍为任何线程所占有时即被销毁,或在占有 mutex 时线程终止,那么行为未定义。mutex 类满足互斥体 (Mutex) 和标准布局类型 (StandardLayoutType) 的全部要求。
std::mutex 既不可复制也不可移动。
嵌套类型
| 名字 | 定义 |
native_handle_type (可选*)
|
由实现定义 |
成员函数
| 构造互斥体 (公开成员函数) | |
| 销毁互斥体 (公开成员函数) | |
operator= [弃置] |
不可复制赋值 (公开成员函数) |
锁定 | |
| 锁定互斥体,若互斥体不可用则阻塞 (公开成员函数) | |
| 尝试锁定互斥体,若互斥体不可用则返回 (公开成员函数) | |
| 解锁互斥体 (公开成员函数) | |
本机句柄 | |
| 返回底层的实现定义的本机句柄对象 (公开成员函数) | |
注解
通常不直接使用 std::mutex:std::unique_lock、std::lock_guard 或 std::scoped_lock(C++17 起) 以更加异常安全的方式管理锁定。
示例
此示例展示 mutex 能如何用于在保护在两个线程间共享的 std::map。
运行此代码
#include <chrono>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include <thread>
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,因为线程 t1/t2 都已完成执行
for (const auto& [url, page] : g_pages)
std::cout << url << " => " << page << '\n';
}
输出:
http://bar => 伪内容
http://foo => 伪内容
参阅
(C++11) |
提供能被同一线程递归锁定的互斥设施 (类) |
(C++11) |
实现严格基于作用域的互斥体所有权包装器 (类模板) |
(C++11) |
实现可移动的互斥体所有权包装器 (类模板) |
(C++17) |
用于多个互斥体的免死锁 RAII 封装器 (类模板) |
(C++11) |
提供与 std::unique_lock 关联的条件变量 (类) |