23人参与 • 2025-07-10 • C/C++
作用:std::condition_variable
是 c++ 多线程编程中用于线程间同步的核心工具,其使用场景和核心价值体现在以下几个方面:
线程需要等待特定条件成立当某个线程必须等待共享资源的某个状态(如队列非空、任务完成、数据就绪等)时,使用条件变量可以避免忙等待(busy-waiting),从而减少 cpu 资源的浪费。
经典场景:notify_one()
或 notify_all()
通知消费者。需要多线程协作完成复杂逻辑当多个线程需要按特定顺序协作时(如线程 a 完成预处理后通知线程 b 执行),条件变量提供了一种高效的协调机制。
示例:主线程等待所有子线程初始化完成后再启动核心逻辑。避免轮询和资源浪费若用 while (条件不满足) { sleep(); }
实现等待,会导致线程频繁切换上下文和无效轮询,而条件变量通过阻塞线程直接释放 cpu,直到被主动唤醒。
需要动态调整线程行为例如,线程池中的工作线程根据任务负载动态休眠或唤醒。
解决线程同步中的“等待-通知”问题条件变量通过 wait() 和 notify_*() 的组合,实现线程间的精准通知机制:
避免虚假唤醒(spurious wakeup)操作系统的底层实现可能导致线程被意外唤醒(即使未收到通知)。条件变量通过 谓词(predicate) 参数(如 cv.wait(lock, []{ return ready; }))确保只有在条件真正满足时才继续执行。
优化锁的粒度条件变量与 std::mutex 配合使用时,允许在等待期间释放锁,其他线程可继续操作共享资源,避免长时间锁竞争。
替代低效的轮询机制相比轮询(如 sleep() + 循环检查),条件变量通过操作系统级的线程调度实现高效阻塞,减少 cpu 占用。
定义共享变量和同步工具:
std::mutex mtx; std::condition_variable cv; bool data_ready = false;
等待线程:
std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return data_ready; }); // 阻塞直到 data_ready 为 true
通知线程:
{ std::lock_guard<std::mutex> lock(mtx); data_ready = true; } cv.notify_one(); // 唤醒一个等待线程
#include <queue> #include <mutex> #include <condition_variable> std::mutex mtx; std::condition_variable cv; std::queue<int> task_queue; void producer() { for (int i = 0; i < 10; ++i) { { std::lock_guard<std::mutex> lock(mtx); task_queue.push(i); } cv.notify_one(); // 通知消费者 } } void consumer() { while (true) { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return !task_queue.empty(); }); // 等待队列非空 int task = task_queue.front(); task_queue.pop(); lock.unlock(); // 处理任务 } }
必须与互斥锁配合使用:
所有对共享变量的修改和访问必须通过互斥锁保护,否则会导致竞态条件(race condition)。
正确处理虚假唤醒:
始终使用带谓词的 wait()
形式(如 cv.wait(lock, predicate)
)。
避免“唤醒丢失”:
确保在修改共享状态后调用 notify_*()
,否则等待线程可能永远阻塞。
std::condition_variable
的核心价值在于通过 等待-通知机制 实现高效的线程同步,适用于需要协调多个线程行为、避免资源浪费的场景。其设计解决了传统轮询的低效问题,并通过与互斥锁的配合优化了多线程程序的性能与安全性。
到此这篇关于c++中std::condition_variable 条件变量的使用的文章就介绍到这了,更多相关c++ std::condition_variable 条件变量内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论