C++ 线程同步工具

oneNeko 于 2022-05-19 发布

在多线程环境下,多个线程同时使用同一个资源可能会发生意想不到的结果,因此需要对线程操作进行同步操作,保证资源使用行为符合预期

C++提供了互斥库<mutex>、条件变量库<condition_variable>、异步操作库<future>。由于C++标准还在不断完善线程同步工具,因此这里只涉及C++11标准

mutex简介

定义于<mutex>,是能用于保护共享数据免受从多个线程同时访问的同步原语。

mutex 提供排他性非递归所有权语义:

std::mutex 既不可复制亦不可移动

mutex成员函数

lock:锁定互斥,若互斥不可用则阻塞
try_lock:尝试锁定互斥,若互斥不可用则返回
unlock:解锁互斥

通用互斥管理

lock_guard:实现严格基于作用域的互斥体所有权包装器
类 lock_guard 是互斥体包装器,为在作用域块期间占有互斥提供便利 RAII 风格机制。创建 lock_guard 对象时,它试图接收给定互斥的所有权。控制离开创建 lock_guard 对象的作用域时,销毁 lock_guard 并释放互斥。lock_guard 类不可复制。

unique_lock:实现可移动的互斥体所有权包装器
类 unique_lock 是通用互斥包装器,允许延迟锁定、锁定的有时限尝试、递归锁定、所有权转移和与条件变量一同使用。类 unique_lock 可移动-满足可移动构造和可移动赋值,但不可复制。类 unique_lock 满足基本可锁定(简单理解为可以lock()和unlock())要求

区别

lock_guard创建时加锁,离开作用域解锁
unique_lock创建时加锁,离开作用域解锁。可以维持锁的状态供后续自行加锁解锁(类似mutex),相对lock_guard更灵活,但要付出额外代价保存状态

条件变量

条件变量是允许多个线程相互交流的同步原语。它允许一定量的线程等待(可以定时)另一线程的提醒,然后再继续。条件变量始终关联到一个互斥
condition_variable 类是同步原语,定义于头文件condition_variable,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知

成员函数

Future

标准库提供了一些工具来获取异步任务(即在单独的线程中启动的函数)的返回值,并捕捉其所抛出的异常。这些值在共享状态中传递,其中异步任务可以写入其返回值或存储异常,而且可以由持有该引用该共享态的 std::future 或 std::shared_future 实例的线程检验、等待或是操作这个状态。 定义于头文件

成员函数