加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

一个消费者和一个两个生产者

发布时间:2020-12-16 07:11:18 所属栏目:百科 来源:网络整理
导读:我在编写这个C代码时遇到问题,我需要让两个生产者拥有自己的缓冲区.然后一个消费者从任一缓冲区消耗一个项目,只在两个缓冲区都为空时才等待.我知道如果消费者等待生成器缓冲区为空,如何编写代码 sem_wait(Xfull);item1 = BufferX[outX];sem_signal(Xempty);s
我在编写这个C代码时遇到问题,我需要让两个生产者拥有自己的缓冲区.然后一个消费者从任一缓冲区消耗一个项目,只在两个缓冲区都为空时才等待.我知道如果消费者等待生成器缓冲区为空,如何编写代码

sem_wait(Xfull);
item1 = BufferX[outX];
sem_signal(Xempty);

sem_wait(Yfull);
item2 = BufferB[outY];
sem_signal(BufferBEmpty);

但我坚持这个.

解决方法

您可以拥有一个信号量来计算两个队列中未消耗项目的总数.生产者发布信息,消费者等待它.一旦消费者成功等待信号量,它就会使用互斥锁来检查每个队列以找到要使用的项目.

sem_t ProducedItems;  // counts total # of unconsumed items in Q's A and B
sem_t Q_A;            // mutex on Q A
sem_t Q_B;            // mutex on Q B

void *consumer(void *arg)
{
  int bias = 0;  // NOTE: could use to not always favor reading from Q A over Q B

  while (1)
  {
    // wait for an item to be produced
    sem_wait(&ProducedItems);

    // find an item to consume
    do 
    {
      sem_wait(&Q_A);
      {
        if (Q A not empty) 
        {
          remove an item from Q A;
          bias = 1;
        }
      }
      sem_post(&Q_A);

      if (got item from A)
        break;

      sem_wait(&Q_B);
      {
        remove an item from Q B;
        bias = 0;
      }
      sem_post(&Q_B);
    } 
    while (0);

    // consume item
  }

  return NULL;
}

如果消费者还需要向生产者发出信号,例如确保他们的Q不会变得太大,那么你也可以为每个生产者提供信号量,表明他们的Q中还剩下多少空间.生产者会等待其信号量,消费者会在他们从各自的Q中删除项目时发布信息.

如果你想将它概括为N个生产Q,那么你可能想要保留一个由互斥锁保护的掩码,它指示哪个Q上有未消耗的项目.

一旦消费者获得了ProducedItems信号量,那么它将锁定掩码以查看哪些Q在其上具有未消耗的项目并对它们进行循环进展以决定下一个应该从哪个Q读取.然后它将从该Q锁定一个项目,如果该Q变空则更新位掩码,释放互斥锁并最终使用该项目.

生产者会将项目放入他们的Q中,如果它已经是空的,那么他们也会锁定全局位掩码并在其中设置其Q位,释放互斥锁然后发布ProducedItems信号量.

或者不是有点掩码,你可以有一个Q的大小数组,虽然这需要生产者每次产生时锁定互斥锁,等等.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读