Namespaces
Variants

std:: notify_all_at_thread_exit

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
notify_all_at_thread_exit
(C++11)
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
定义于头文件 <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...)> 的公开成员函数)