c++11 生产者和消费者模型

一段简单的示例代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
int i = 0;
std::mutex mtx;
std::condition_variable condition_in, condition_out;
void in(int id)
{
    while (true)
    {
        //(1)
        std::unique_lock<std::mutex> in(mtx);
        condition_in.wait(in, [id](){
            std::cout << "condition_in.wait id:" << id << std::endl;
            return i < 5; 
        });
        std::cout << "thread id:"<<id<<"# "<<"===>"<<++i<<std::endl;
        //(2)
        condition_out.notify_one();
        //(3)
    }
}
void out(int id)
{
    while (true)
    {
        std::unique_lock<std::mutex> in(mtx);
        condition_out.wait(in, [id](){
            std::cout << "condition_out.wait id: " << id <<std::endl;
            return i > 1;
        });
        i -= 2;
        std::cout << "thread id:" << id<<"# "<<"===>" <<i << std::endl;
        condition_in.notify_one();
    }
}
void main()
{
    std::thread t1(in,0);
    std::thread t2(out,1);
    //std::thread t3(out,2);
    //std::thread t4(out,3);
    //std::thread t5(out,4);

    t1.join();
}

std::unique_lock

std::unique_lock 是一个使用RAII机制来管理 std::mutex 的一个类,相比于 std::lock_guard 有更灵活的方式,但会比 std::lock_guard 使用更多的空间。

Member functions

Locking/unlocking

lock
try_lock
try_lock_for
try_lock_until
unlock

Modifiers

operator= (Move-assign unique_lock)
swap
release

Observers

owns_lock
operator bool (Return whether it owns a lock)
mutex

运行结果

单消费者单生产者

condition_in.wait id:0
thread id:0# ===>1
condition_out.wait id: 1
condition_in.wait id:0
thread id:0# ===>2
condition_in.wait id:0
thread id:0# ===>3
condition_out.wait id: 1
thread id:1# ===>1
condition_in.wait id:0
thread id:0# ===>2
condition_out.wait id: 1
thread id:1# ===>0
condition_in.wait id:0
thread id:0# ===>1
condition_out.wait id: 1
condition_in.wait id:0
thread id:0# ===>2
condition_in.wait id:0
thread id:0# ===>3
condition_out.wait id: 1
thread id:1# ===>1
condition_in.wait id:0
thread id:0# ===>2
condition_out.wait id: 1
thread id:1# ===>0

结果大致如预期,但是通过观察发现产品的个数总是以0->1->2->3->1->2->0的规律变化,按理说每次产品增加到2之后唤醒消费者线程应该就会将2个产品取走了。通过分析输出日志,应该是因为被condition阻塞的线程从唤醒到重新上锁的时间要长于 std::unique_lock 锁争用时直接上锁的时间。另外,启动消费者和生产者线程的先后顺序也会影响刚开始的输出序列,但整体的变化规律不会变。在(1)处插入

if(i > 1)

然后先启动t2,再启动t1线程,仍然可以观察到相同序列,基本证明猜想正确。
多消费者多生产者的情况也完全符合预期。不过经过一番尝试,并没有模拟出虚假唤醒的情况,有待进一步考察。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值