条件变量与工作线程模式
使用 std::condition_variable 和经典的工作线程池模式协调线程
条件变量与工作线程模式 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
什么是条件变量
条件变量可以让线程等待,直到另一个线程发出条件已改变的信号。它用于协调生产者和消费者。
std::condition_variable 基础
条件变量与 std::mutex 和谓词配合使用。等待线程在等待期间释放锁,并在唤醒时重新获取锁。
#include <condition_variable>
#include <mutex>
#include <queue>
std::mutex mtx;
std::condition_variable cv;
std::queue<int> tasks;
bool done = false;等待条件
请使用 cv.wait(lock, predicate)。它会以原子方式解锁互斥量并进入休眠,直到收到通知。唤醒后,它会重新加锁并检查谓词;如果谓词为假,就会再次休眠。
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });通知
生产者线程更改状态后,会调用 cv.notify_one() 或 cv.notify_all()。更改状态期间应持有锁。
{
std::lock_guard<std::mutex> lock(mtx);
tasks.push(42);
}
cv.notify_one();生产者-consumer 模式
经典示例:生产者推送任务;consumer 等待任务。
void consumer() {
while (true) {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return !tasks.empty() || done; });
if (done && tasks.empty()) break;
int task = tasks.front();
tasks.pop();
lock.unlock();
process(task);
}
}虚假唤醒
等待条件变量的线程可能在未收到通知的情况下被唤醒。因此,wait 接受一个谓词——每次唤醒时都会重新检查该谓词。
notify_one 与 notify_all
当一个等待者即可继续执行时,请使用 notify_one。当状态更改会影响所有等待者时,请使用 notify_all(例如发送关闭信号时)。
定时等待
wait_for(lock, duration) 和 wait_until(lock, time_point) 会在收到通知或 timeout 后唤醒。
if (cv.wait_for(lock, 1s, [] { return ready; })) {
/* condition met */
} else {
/* timed out */
}工作线程池骨架
一种常见模式是:固定数量的工作线程从共享队列中取出任务。可使用互斥锁、条件变量、队列和原子停止标志来构建。
避免丢失唤醒
请始终在更改状态期间持有互斥锁,同时修改共享状态并调用 notify_*(在调用通知前刚好释放锁也可以,但请确保顺序正确)。否则,等待者可能会错过通知。
std::counting_semaphore(C++20)
对于简单的基于计数的信号传递,C++20 新增了 std::counting_semaphore;对于某些模式,它比条件变量更简单。
谨防死锁
等待条件变量时持有多个锁可能导致死锁。请以一致的顺序获取锁,并对多个互斥锁使用 std::scoped_lock。
快速检查
即使您只是想等待通知,cv.wait(lock, predicate) 为什么仍然需要一个谓词?
回顾
条件变量用于协调等待状态更改的线程。请使用 wait(lock, predicate) 处理虚假唤醒,在互斥锁保护下修改状态,然后调用 notify_one 或 notify_all。
用 AI 导师学习 C++ — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 51
- 课程
- 203
常见问题解答
「条件变量与工作线程模式」课时是免费的吗?
是的 — 「条件变量与工作线程模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「条件变量与工作线程模式」这节课中我会学到什么?
使用 std::condition_variable 和经典的工作线程池模式协调线程 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「条件变量与工作线程模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。