std:: notify_all_at_thread_exit
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
定义于头文件
<condition_variable>
|
||
|
void
notify_all_at_thread_exit
(
std::
condition_variable
&
cond,
std:: unique_lock < std:: mutex > lk ) ; |
(C++11 起) | |
notify_all_at_thread_exit
提供了一种机制,用于通知其他线程某个给定线程已完全执行完毕,包括销毁所有
thread_local
对象。其运行机制如下:
- 先前获取的锁 lk 的所有权被转移至内部存储。
-
执行环境被修改为:当当前线程退出时,条件变量
cond
会被通知,如同执行了
lk.
unlock
(
)
;
cond. notify_all ( ) ; 操作。
隐式的 lk. unlock ( ) 操作 顺序晚于 与当前线程关联的所有具有 thread_local存储期 的对象的析构。
若满足以下任一条件,则行为未定义:
- lk 未被调用线程锁定。
-
如果其他线程也在等待
cond
,则
lk.
mutex
(
)
与那些线程在
cond
上调用的等待函数(
wait、 wait_for 和 wait_until )解锁的互斥锁不同。
目录 |
注释
使用 std::promise 或 std::packaged_task 提供的功能可以实现等效效果。
提供的锁
lk
将保持持有状态直至线程退出。一旦调用此函数,其他线程将无法再获取同一把锁以等待
cond
。若有线程正在等待此条件变量,需确保在持有
lk
锁期间满足被等待的条件,且在调用
notify_all_at_thread_exit
前不得释放并重新获取该锁,以避免其他线程出现虚假唤醒导致的混乱。
在典型使用场景中,该函数是分离线程最后调用的功能。
参数
| cond | - | 线程退出时需通知的条件变量 |
| lk | - | 与条件变量 cond 关联的锁 |
返回值
(无)
示例
此部分代码片段展示了如何使用
notify_all_at_thread_exit
来避免在线程局部变量正在被析构的过程中访问依赖于这些线程局部变量的数据:
#include <cassert> #include <condition_variable> #include <mutex> #include <string> #include <thread> std::mutex m; std::condition_variable cv; bool ready = false; std::string result; // 任意类型 void thread_func() { thread_local std::string thread_local_data = "42"; std::unique_lock<std::mutex> lk(m); // 使用线程局部数据为 result 赋值 result = thread_local_data; ready = true; std::notify_all_at_thread_exit(cv, std::move(lk)); } // 1. 销毁线程局部变量; // 2. 解锁互斥锁; // 3. 通知条件变量。 int main() { std::thread t(thread_func); t.detach(); // 执行其他工作 // ... // 等待分离的线程 std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{ return ready; }); // result 已就绪且线程局部变量析构已完成,无未定义行为 assert(result == "42"); }
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| LWG 2140 | C++11 |
对
notify_all_at_thread_exit
的调用
与等待 cond 的函数调用同步 |
更新了同步
要求 |
参见
|
设置结果为指定值,但仅在线程退出时传递通知
(
std::promise<R>
的公开成员函数)
|
|
|
执行函数并确保结果仅在当前线程退出时才准备就绪
(
std::packaged_task<R(Args...)>
的公开成员函数)
|