C 同步制作人及;带循环缓冲区的耗电元件

C 同步制作人及;带循环缓冲区的耗电元件,c,concurrency,producer-consumer,C,Concurrency,Producer Consumer,我有一个生产者和一个消费者。生产者在给定的共享内存区域上写入固定大小的项目,消费者检索这些项目 生产者可以明显地慢于或快于消费者 我们想要的是 如果生产者的运行速度比消费者快,当它填充循环缓冲区时,它会继续在最旧的帧上写入(当然,消费者正在使用的帧除外-我强调这一点,生产者和消费者必须在解决方案中同步,因为它们是不相关的进程) 相反,如果消费者的速度比生产者快,那么它必须等待新的帧,并在它出现时使用它 我发现生产者/消费者的实现使用循环缓冲区,但只有那些不尊重第一个请求的实现(即,如果循环缓冲区

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

生产者可以明显地慢于或快于消费者

我们想要的是

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

  • 相反,如果消费者的速度比生产者快,那么它必须等待新的帧,并在它出现时使用它

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

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


    <>谢谢。

    < p>听起来你想使用C++中提供的一个C++,而不是C++。如果你的生产者和消费者是不同的线程,那么你也需要一个互斥体来保护队列结构。

    听起来好像你想使用C++中提供的一个C++使用的。不是C。如果您的生产者和消费者是不同的线程,那么您还需要一个互斥来保护队列结构。

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

    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();
      }
    
    };
    
    类采样同步器{
    互斥多路复用器;
    条件变量条件;
    无符号整数;
    条件变量条件;
    bool-prod;
    公众:
    SampleSynchronizer():con_num(0),prod(false){
    } 
    void consumerLock(){
    独特的锁柜(mux);
    while(prod)
    备用等待(储物柜);
    con_num++;
    }
    void consumerUnlock(){
    锁柜(mux);
    con_num--;
    con_cond.notify_one();
    }
    void producerLock(){
    独特的锁柜(mux);
    而(con_num>0)
    con_.cond.wait(储物柜);
    prod=true;
    }
    bool producerRTLock(){
    锁柜(mux);
    如果(con_num>0)
    返回false;
    prod=true;
    返回true;
    }
    void producerUnlock(){
    锁柜(mux);
    prod=false;
    第二次通知所有人();
    }
    };
    
    基本上,当用户速度较慢时,这意味着没有人在使用缓冲区,因此删除新帧和覆盖旧帧之间没有区别。因此,下面的代码可能会有所帮助。producerRTLock无法锁定缓冲区,因为存在使用buffer的使用者,因此在应用程序级别,您可以指示丢弃帧

    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();
      }
    
    };
    
    类采样同步器{
    互斥多路复用器;
    条件变量条件;
    无符号整数;
    条件变量条件;
    bool-prod;
    公众:
    SampleSynchronizer():con_num(0),prod(false){
    } 
    void consumerLock(){
    独特的锁柜(mux);
    while(prod)
    备用等待(储物柜);
    con_num++;
    }
    void consumerUnlock(){
    锁柜(mux);
    con_num--;
    con_cond.notify_one();
    }
    void producerLock(){
    独特的锁柜(mux);
    而(con_num>0)
    con_.cond.wait(储物柜);
    prod=true;
    }
    bool producerRTLock(){
    锁柜(mux);
    如果(con_num>0)
    返回false;
    prod=true;
    返回true;
    }
    void producerUnlock(){
    锁柜(mux);
    prod=false;
    第二次通知所有人();
    }
    };
    
    听起来您只是想删除一个限制,有人必须将其编码到您所看到的实现中。如果您只是删除阻止生产者覆盖其缓冲区中数据的任何代码,我认为它的工作原理与您正在寻找的一样。@Carl-除了让头部覆盖尾部之外,您还需要提前尾部指针,否则您所做的工作就相当于清空整个缓冲区。@Carl-不,仅仅允许生产者覆盖旧的缓冲区删除信号量就意味着覆盖消费者正在消费的项目。我需要的是一个同步的生产者-消费者实现。您只需复制消费者需要的数据,并让它处理副本,那么缓冲区中的原始数据就可以自由覆盖。你将要覆盖的内容将是它下一次使用的内容(缓冲区中当前最旧的项目)。@Greg:不,我不能再复制一次。此外,复制需要时间。如果制作人在我复制时在原始缓冲区上写入内容呢?当消费者在一个项目上做东西时,无论是复制还是其他什么,生产者都不能碰它。听起来你只是想取消一个限制,有人必须在你看到的实现中编码。如果您只是删除阻止生产者覆盖其缓冲区中数据的任何代码,我认为它的工作原理与您正在寻找的一样。@Carl-除了让头部覆盖尾部之外,您还需要提前尾部指针,否则您所做的工作就相当于清空整个缓冲区。@Carl-不,仅仅允许生产者覆盖旧的缓冲区删除信号量就意味着覆盖消费者正在消费的项目。我需要的是一个同步的生产者-消费者实现。您只需复制消费者需要的数据,并让它处理副本,那么缓冲区中的原始数据就可以自由覆盖。你呢