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

C++ Condition Variable调用notify后主线程无法唤醒问题

主线程等待条件变量无法被工作线程唤醒的问题解决

问题描述

我编写了一段多线程代码,主线程等待条件变量,工作线程负责通知它。代码示例如下:

#include <thread>
#include <condition_variable>
#include <mutex>
#include <iostream>

std::mutex mt;
std::condition_variable cv;
bool flag = false;

void worker() {
  std::unique_lock lock(mt);
  std::cout << "Worker started.\n";
  flag = true;
  lock.release();
  cv.notify_one();
  std::cout << "Worker done.\n";
}

int main() {
  std::thread thread(worker);
  std::unique_lock lock(mt);
  std::cout << "Main waiting.\n";
  cv.wait(lock, [](){ std::cout << "Main checking: " << flag << '\n'; return flag; });
  std::cout << "Main done.\n";
  thread.join();
}

原本预期会出现以下两种情况之一:

  1. 主线程先获取锁,等待工作线程完成;
  2. 工作线程先获取锁,完成后主线程无需等待。

但实际运行时主线程始终无法唤醒,输出内容如下:

Main waiting.
Main checking: 0
Worker started.
Worker done.

程序最终陷入挂起状态,请问该如何解决此问题?

问题根源

问题出在工作线程中的lock.release()调用——std::unique_lock::release()的作用是返回指向互斥量的指针,并释放unique_lock对该互斥量的所有权,但不会改变互斥量的锁定状态。

你的代码中,unique_lock是在持有锁的情况下调用release的,这导致互斥量一直处于锁定状态。当工作线程调用cv.notify_one()后,主线程被唤醒,但它需要重新获取互斥量才能继续执行(条件变量的wait唤醒后会自动尝试加锁),而此时互斥量仍然是锁定状态,主线程因此阻塞在获取锁的步骤,表现为程序挂起。

解决方法

方法一:使用unlock()替代release()

直接调用lock.unlock()手动解锁互斥量,这样主线程唤醒后可以正常获取锁:

void worker() {
  std::unique_lock lock(mt);
  std::cout << "Worker started.\n";
  flag = true;
  lock.unlock(); // 手动解锁互斥量
  cv.notify_one();
  std::cout << "Worker done.\n";
}

方法二:利用unique_lock的作用域自动解锁

将unique_lock放在局部作用域中,当作用域结束时,unique_lock会自动解锁互斥量,无需手动调用:

void worker() {
  {
    std::unique_lock lock(mt);
    std::cout << "Worker started.\n";
    flag = true;
  } // lock离开作用域,自动解锁互斥量
  cv.notify_one();
  std::cout << "Worker done.\n";
}

方法三:若必须使用release(),需先手动解锁

如果一定要保留release()调用,必须先调用unlock()释放互斥量,再调用release()放弃所有权:

void worker() {
  std::unique_lock lock(mt);
  std::cout << "Worker started.\n";
  flag = true;
  lock.unlock(); // 先解锁互斥量
  lock.release(); // 再释放unique_lock对互斥量的所有权
  cv.notify_one();
  std::cout << "Worker done.\n";
}

内容的提问来源于stack exchange,提问作者Weak to Enuma Elish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:28:17