同步制作人和带有循环缓冲区的消费者

发布于 2024-08-07 16:54:50 字数 489 浏览 6 评论 0原文

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

生产者可能会随机地明显慢于或快于消费者。

我们想要的是,

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

  2. 如果消费者比生产者快,它必须等待新帧并在新帧出现时使用它。

    相反,如果消费者比生产者快

我找到了具有循环缓冲区的生产者/消费者的实现,但只有那些不尊重第一个请求的实现(即,如果循环缓冲区已满,它们会等待消费者完成,而我想要的是覆盖最旧的帧)。

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

非常感谢。

I've got a producer and a consumer. The producer writes fixed size items on a given shared memory area, and the consumer retrieves them.

The producer can be noticeably slower or faster than the consumer, randomly.

What we want is that

  1. If the producer is running faster than the consumer, when it fills the circular buffer, it keeps writing on the oldest frames (other than the one that the consumer is consuming, of course - I stress this point, producer and consumer must be synchronized in the solution, because they are unrelated processes).

  2. If, instead, the consumer is faster than the producer, it must wait for a new frame and consume it when it's there.

I found implementations of producer/consumers with circular buffers, but only ones that didn't respect the first request (ie, if the circular buffer is full, they wait for the consumer to finish, while what I want is to overwrite the oldest frames).

I'd prefer not to roll my own (prone to bugs) solution, but use a pre-canned, tested one. Can someone point me to a good C implementation? (C++ is also ok).

Many thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

撞了怀 2024-08-14 16:54:50

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

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();
  }

};

Basically when the consumers are slow, it means that no one is using the buffer, so there is no difference between dropping the new frames and overriding the old frames. So maybe the following code can help. The producerRTLock cannot lock the buffer because there are consumers using the bufffer and therefore at the application level you can indicate to drop the frames.

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();
  }

};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文