用记录型信号量解决生产者-消费者问题

问题描述:

有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将其所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,既不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区投放产品。

参考代码:

int in = 0, out = 0;//in: 输入指针, out: 输出指针;
item buffer[n];//n个缓冲区组成的数组;
semaphore mutex = 1, full = 0, empty = n;
//mutex: 互斥信号量, 生产者进程和消费者进程都只能互斥访问缓冲区;
//full: 资源信号量, 满缓冲区的数量;
//empty: 资源信号量, 空缓冲区的数量;//信号量不允许直接参与运算, 故都要定义;

//生产者程序;
void Producer() {
  do {
      生产者生产一个产品nextp;
      wait(empty);//申请一个空缓冲区;
      wait(mutex);//申请临界资源;
      buffer[in] = nextp;//将产品添加到缓冲区;
      in = (in + 1) % n;//类似于循环队列;
      signal(mutex);//释放临界资源;
      signal(full);//释放一个满缓冲区;
  } while (TRUE);
}

//消费者程序;
void Producer() {
  do {
      wait(full);//申请一个满缓冲区;
      wait(mutex);//申请临界资源;
      nextc = buffer[out];//将产品从缓冲区取出;
      out = (out + 1) % n;//类似于循环队列;
      signal(mutex);//释放临界资源;
      signal(empty);//释放一个空缓冲区;
      消费者将一个产品nextc消费; 
 } while (TRUE);
}

注意:

  1. 生产者与消费者进程对资源信号量的申请与释放情况刚好相反(生产者是申请空,释放满;消费者是申请满,释放空)。
  2. 应先执行对资源信号量的申请,然后再对互斥信号量进行申请操作,否则会因起死锁(如果先申请互斥信号量再申请资源信号量,则可能发生一个进程申请互斥信号量成功,得到临界资源,再申请资源信号量失败,导致该进程带着临界资源进入阻塞状态,造成死锁)。

参考资料:《计算机操作系统(第四版)》(西安电子科技大学出版社)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 文章内容: 生产者-消费者问题的模拟场景(代码实现) 深入理解(信号量操作顺序) 先把概念丢一边,来一起下个馆子吧...
    JABread阅读 2,063评论 0 4
  • ** 本文摘自汤小丹主编《计算机操作系统》(第三版)2.3 进程同步 ** 在 OS 中引入进程后,虽然提高了资源...
    刘帅_阅读 3,159评论 0 0
  • 背井离乡,离开熟悉的人和地方,去远方生活,积攒起所有的力量去拼搏去呐喊,为了什么。有时候想想就让人悲伤,有权有势的...
    麦兜兜有糖阅读 278评论 0 0
  • 1.渐变轮播,图片淡入淡出 代码预览代码 2.无限循环滚动轮播效果 代码预览代码 3.全屏轮播(图片大加载比较慢)...
    泰格_R阅读 241评论 1 2
  • 在学习并观察自己情绪的过程中,我逐渐梳理出自己在调整自我情绪中的几个部分:觉察,观察,思考和调频。 觉察 觉察是指...
    不糊涂的小财迷阅读 392评论 2 1