You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何condition_variable的析构函数会导致程序挂起?

为何condition_variable的析构函数会导致程序挂起?

嘿,这个问题的核心原因其实很明确:当你的全局条件变量触发析构时,还有线程正阻塞在它的wait调用上,咱们结合你的代码一步步说清楚:

首先先看你提供的最小复现代码(MRE):

#include <mutex>
#include <condition_variable>
#include <thread>
#include <unistd.h>

std::mutex mu;
std::condition_variable cv;
void test(){
    std::unique_lock lk(mu);
    cv.wait(lk);
}
int main(){
 std::thread(test).detach();
 sleep(3);
}

问题拆解

  1. 主线程启动了一个detach的后台线程,这个线程一启动就拿到互斥锁,然后卡在cv.wait(lk)上——它一直在等待条件变量被唤醒,但主线程从头到尾都没调用cv.notify_one()或者cv.notify_all()来通知它。
  2. 主线程sleep3秒后就直接退出了,这时候全局的cv和mu会被自动析构。而C++标准库的condition_variable底层通常是基于POSIX的pthread_cond_t实现的,对应的销毁函数pthread_cond_destroy有个硬性要求:调用它的时候,绝对不能有任何线程还在等待这个条件变量。
  3. 你的后台线程此时还死死卡在wait上,这就导致pthread_cond_destroy阻塞,最终整个程序挂住,也就是你看到的卡在pthread_cond_destroy的情况。

解决思路

你可以从两个方向修复这个问题:

  • 主线程退出前主动唤醒后台线程:在sleep(3)之后加一段代码,通知条件变量让后台线程结束等待,比如:
    {
        std::lock_guard<std::mutex> lk(mu);
        cv.notify_all();
    }
    
  • 不要使用detach,改用join等待后台线程结束:把std::thread(test).detach();改成std::thread t(test); t.join();,这样主线程会等后台线程完成后再退出,避免全局变量先于线程析构。

备注:内容来源于stack exchange,提问作者DarkRise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 08:47:59