同步制片人&消费者使用循环缓冲区

时间:2009-10-14 16:39:25

标签: c concurrency producer-consumer

我有一个制作人和一个消费者。生产者在给定的共享内存区域写入固定大小的项目,并且消费者检索它们。

生产者可以比消费者明显更慢或更快,随机。

我们想要的是

  1. 如果生产者的运行速度比消费者快,当它填充循环缓冲区时,它会继续写入最旧的框架(当然消费者消费的框架除外) - 我强调这一点,生产者消费者 必须 在解决方案中同步,因为它们是不相关的流程。)

  2. 相反,如果消费者比生产者更快,那么它必须等待一个新的框架并在它出现时消耗它。

  3. 我发现使用循环缓冲区的生产者/消费者的实现,但只有那些不尊重第一个请求的实现(即,如果循环缓冲区已满,它们等待消费者完成,而我想要的是覆盖最古老的帧。)

    我不想推出自己的(容易出错的)解决方案,而是使用预先测试的,经过测试的解决方案。有人能指出我一个好的C实现吗? (C ++也没关系。)

    非常感谢。

2 个答案:

答案 0 :(得分:0)

基本上当消费者很慢时,这意味着没有人使用缓冲区,因此删除新帧和覆盖旧帧之间没有区别。所以也许以下代码可以提供帮助。 producerRTLock无法锁定缓冲区,因为有消费者使用bufffer,因此在应用程序级别您可以指示丢弃帧。

class SampleSynchronizer {

  mutex mux;

  condition_variable con_cond;
  unsigned int con_num;

  condition_variable pro_cond;
  bool prod;

public:

  SampleSynchronizer(): con_num(0), prod(false) {
  } 

  void consumerLock() {
    unique_lock<mutex> locker(mux);
    while(prod)
      pro_cond.wait(locker);

    con_num++;
  }

  void consumerUnlock() {
    lock_guard<mutex> locker(mux);
    con_num--;
    con_cond.notify_one();
  }

  void producerLock() {
    unique_lock<mutex> locker(mux);
    while(con_num > 0)
      con_cond.wait(locker);

    prod = true;
  }

  bool producerRTLock() {
    lock_guard<mutex> locker(mux);
    if(con_num > 0)
      return false;

    prod = true;
    return true;
  }

  void producerUnlock() {
    lock_guard<mutex> locker(mux);
    prod = false;
    pro_cond.notify_all();
  }

};

答案 1 :(得分:-1)

听起来你想使用C ++的double ended queue中提供的Standard Template Library (STL).但是它使用的是C ++,而不是C.如果你的生产者和消费者是不同的线程,那么你还需要一个互斥量来保护队列结构。