如何使用std::mutex与condition_variable实现经典生产者消费者模型?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1165个文字,预计阅读时间需要5分钟。
由于生产者和消费者在等待对方时不能直接占有锁,否则对方将永远无法获得锁,也无法唤醒你。此时,必须将等待逻辑从临界区中分离出来,使用`std::condition_variable`配合`std::unique_lock`来实现。
以下是修改后的代码片段:
常见错误现象:std::condition_variable::wait() 被调用时没传 std::unique_lock,或者传了但锁已释放;或者忘了在 wait() 的 lambda 条件里检查实际状态(比如队列是否真非空),导致虚假唤醒后直接读空队列崩溃。
- 必须用
std::unique_lock(不能用std::lock_guard),因为wait()会内部释放并重新获取它 - 条件判断必须写在
wait()的第二个参数 lambda 里,且该 lambda 返回true才继续执行,否则继续等 - 所有对共享队列的读写操作,都必须包裹在同一个
std::unique_lock作用域内
如何避免 notify_one() 唤醒错线程?
用两个独立的 std::condition_variable:一个专管“队列有数据可取”(not_empty),另一个专管“队列有空位可放”(not_full)。
本文共计1165个文字,预计阅读时间需要5分钟。
由于生产者和消费者在等待对方时不能直接占有锁,否则对方将永远无法获得锁,也无法唤醒你。此时,必须将等待逻辑从临界区中分离出来,使用`std::condition_variable`配合`std::unique_lock`来实现。
以下是修改后的代码片段:
常见错误现象:std::condition_variable::wait() 被调用时没传 std::unique_lock,或者传了但锁已释放;或者忘了在 wait() 的 lambda 条件里检查实际状态(比如队列是否真非空),导致虚假唤醒后直接读空队列崩溃。
- 必须用
std::unique_lock(不能用std::lock_guard),因为wait()会内部释放并重新获取它 - 条件判断必须写在
wait()的第二个参数 lambda 里,且该 lambda 返回true才继续执行,否则继续等 - 所有对共享队列的读写操作,都必须包裹在同一个
std::unique_lock作用域内
如何避免 notify_one() 唤醒错线程?
用两个独立的 std::condition_variable:一个专管“队列有数据可取”(not_empty),另一个专管“队列有空位可放”(not_full)。

