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

C++多线程notify机制疑问:关于condition_variable的三个问题

多线程条件变量常见疑问解答

问题1:为什么Thread2获取锁后无需再次notify?

当Thread1调用notify_all()后,Thread2、3、4都会被唤醒,进入锁的竞争队列。Thread2拿到锁后,会执行while (!ready)的判断——此时ready已经被go()设置为true,所以这个条件不成立,Thread2不会进入wait(),直接执行后续打印逻辑。

而Thread3、4在被唤醒后,会继续竞争锁,等它们拿到锁时,ready依然是true,同样不会进入wait(),自然不需要额外的notify。核心是条件变量的wait只和谓词(这里是ready状态)绑定,notify只是触发线程去检查条件,当条件已经永久满足时,线程不会再休眠。

问题2:示例中后续线程如何被唤醒?notify_all后线程不再休眠吗?

go()里的notify_all()已经把所有等待在cv上的线程全部唤醒了,这些线程会加入锁的竞争队列。当第一个线程执行完打印、释放锁后,其他被唤醒的线程会继续竞争锁:拿到锁后检查ready是true,直接执行打印,不需要再次被notify。

不是说notify_all后线程永远不会休眠——如果ready没被设置为true,线程被唤醒后检查条件不满足,会再次调用wait()进入休眠,这时候才需要新的notify。但在这个示例里,ready被设置为true后就不会再改变,所以所有被唤醒的线程都不会再休眠。

问题3:调用wait时,线程是否仅在条件不满足时休眠?条件满足时多线程留在执行队列?

是的。调用cv.wait(lck)时,线程会先检查谓词(示例里的!ready):

  • 如果条件不满足(ready为false),线程会释放持有的锁,进入休眠状态,等待被notify唤醒;
  • 如果条件满足(ready为true),线程会直接跳过wait(),继续执行后续逻辑。

当多个线程的条件都满足时,它们会处于锁的竞争队列中,依次获取锁执行代码,不会进入休眠。


示例代码

#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void print_id (int id) {
  std::unique_lock<std::mutex> lck(mtx);
  while (!ready) cv.wait(lck);
  // ...
  std::cout << "thread " << id << '\n';
}

void go() {
  std::unique_lock<std::mutex> lck(mtx);
  ready = true;
  cv.notify_all();
}

int main ()
{
  std::thread threads[10];
  // spawn 10 threads:
  for (int i=0; i<10; ++i)
    threads[i] = std::thread(print_id,i);

  std::cout << "10 threads ready to race...\n";
  go();                       // go!

  for (auto& th : threads) th.join();

  return 0;
}

内容的提问来源于stack exchange,提问作者AKASH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:27:10