多线程之生产者消费者问题

在多线程编程过程中,为了保证是原子操作,必须处理好线程之间的同步和互斥,生产者消费者问题即是线程间同步和互斥的经典例子。

生产者消费者问题的描述:

生产者负责生产“产品”,消费者负责消费“产品”,当生产的产品满时(假设有一个生产的流水线),需等待消费者消费产品后才可以生产产品,不然就会溢出,当流水线上没有产品时,消费者就等待生产者生产产品。

问题分解如下:

(1)一个生产者对应一个生产者线程,多个生产者就对应多个生产者线程,因此需注意多个生产者(也就是多个线程)之间的互斥(用互斥锁);

(2)消费者问题同(1);

(3)生产者和消费者需处理好线程同步问题,因为生产者在缓冲区为满时需等待,在消费者为缓冲区为空时需等待,生产者在生产“产品”后需告诉消费者,消费者在消费“产品”后需告诉生产者(使用信号量或者是互斥锁+条件变量)。

实现思路如下:

第一种方法:

采用信号量,信号量是常见的一种线程同步方式,它的特点是它是一个非负整数,当获得(P)某一个信号量时,该信号量的值减去1,当释放(V)一个信号量时,该信号量的值加1;当信号量的值为0时,所有试图获得(P)该信号量的操作都将阻塞等待,直到该信号量值大于0。

在生产者消费者问题中,设置两个信号量:S1--表示缓冲区空的个数  S2--表示缓冲区满的个数,很显然,初始状态下:S1 = n ,S2 = 0;另外还需设置一个互斥锁m,用来多个线程互斥。

伪代码如下:

producer

{

     //其他操作....

      P(S1)  //当某一个生产者获取时就会减一,当减到0时会等待

      P(m)   //互斥操作

      //生产者开始生产数据,即往缓冲区送数据

      V(m)

      V(S2) //当生产者生产数据后,S2加1

}


consumer

{

  P(S2)

  P(m)

  //消费者消费数据,即从缓冲区取数据

  V(m)

  V(S1)//消费者消费数据后,相应的S1加1

}


第二种方法:互斥锁(m)+条件变量(not_full和not_empty)

伪代码如下:

producer

{

   P(m)

   while(缓冲区为满)

       {

              not_full.wait() //当为满时,等待,进入休眠

       }

    生产者生产数据,往缓冲区放数据

    V(m)

    not_empty.notify() //通知消费者缓冲区不空

}


consumer

{

    P(m)

     while(缓冲区为空)

     {

           not_empty.wait();//当无产品时,消费者等待不空

     }

   ......  //消费者消费产品,从缓冲区中取数据

    V(m)

     not_full.notify();//通知生产者不满了。

}

其实第二种方式封装一下就是实现了有边界的阻塞队列,以后总结。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值