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.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 的公开成员函数)
执行函数,并确保结果仅在一旦当前线程退出时就绪
(std::packaged_task 的公开成员函数)

版本历史

  • (当前 | 先前 2017年8月27日 (日) 22:01Fruderica讨论 | 贡献. . (2,924字节) (-2,175). . (撤销)
  • 当前 | 先前 2013年7月2日 (二) 11:32P12bot讨论 | 贡献 . . (5,099字节) (-74). . (Use {{lc}}. Update links. Various fixes.) (撤销)
  • 当前 | 先前 2012年11月2日 (五) 19:33P12bot讨论 | 贡献 . . (5,173字节) (+353). . (r2.7.3) (机器人添加:de, en, es, fr, it, ja, pt, ru) (撤销)
  • 当前 | 先前 2012年10月26日 (五) 03:08P12讨论 | 贡献 . . (4,820字节) (0). . (1个修订: Translate from the English version) (撤销)
  • 当前 | 先前) 2012年10月25日 (四) 12:00TranslationBot讨论 | 贡献. . (4,820字节) (+4,820). . (Translated from the English version using Google Translate)