std::notify_all_at_thread_exit

来自cppreference.com
< cpp‎ | thread
 
 
线程支持库
线程
(C++11)
(C++20)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
互斥
(C++11)
通用锁管理
(C++11)
(C++11)
(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
条件变量
notify_all_at_thread_exit
(C++11)
(C++11)
信号量
闩与屏障
(C++20)
(C++20)
future
(C++11)
(C++11)
(C++11)
(C++11)
 
定义于头文件 <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 的所有权转移到内部存储。
  • 修改执行环境,以令当前线程退出时,如同以下列方式通知 condition_variable cond

lk.unlock();
cond.notify_all();

隐含的 lk.unlock 后序于(定义于 std::memory_order )关联到当前线程的,所有拥有线程局域存储期的对象析构。

等价的效果可以用 std::promisestd::packaged_task 所提供的设施达成。

注意

若当前线程未锁定 lock.mutex() ,则调用此函数是未定义行为。

lock.mutex() 与所有其他等待在同一条件变量上的线程所用的互斥不相同,则调用此函数是未定义行为。

保有提供的锁 lk 直至线程退出。一旦调用此函数,则无更多线程可获得相同的锁,以在 cond 上等待。若某线程在此条件变量上等待,则它在虚假唤醒时不应试图释放和重获得锁。

典型使用情况中,此函数是被脱附线程所做的最后行动。

参数

cond - 在线程退出时通知的 conditional_variable
lk - 关联到 condition_variable cond 的锁

返回值

(无)

示例

此部分代码零碎地描绘 notify_all_at_thread_exit 能如何用于避免在线程局域对象处于被析构过程时,访问依赖于它们的数据:

#include <mutex>
#include <thread>
#include <condition_variable>
 
std::mutex m;
std::condition_variable cv;
 
bool ready = false;
ComplexType result;  // 一些任意类型
 
void thread_func()
{
    std::unique_lock<std::mutex> lk(m);
    // 用 thread_local 数据赋值给 result
    result = function_that_uses_thread_locals();
    ready = true;
    std::notify_all_at_thread_exit(cv, std::move(lk));
} // 1. 销毁 thread_local 对象, 2. 解锁互斥, 3. 通知 cv
 
int main()
{
    std::thread t(thread_func);
    t.detach();
 
    // 做其他工作
    // .…
 
    // 等待脱附的线程
    std::unique_lock<std::mutex> lk(m);
    while(!ready) {
        cv.wait(lk);
    }
    process(result); // result 已准备且 thread_local 析构函数已完成
}

参阅

设置结果为指定值,同时仅在线程退出时分发提醒
(std::promise<R> 的公开成员函数)
执行函数,并确保结果仅在一旦当前线程退出时就绪
(std::packaged_task<R(Args...)> 的公开成员函数)