无优先级反转的环形缓冲区

| 我有一个高优先级的流程,需要将数据传递给低优先级的流程。我已经编写了一个基本的环形缓冲区来处理数据传递:
class RingBuffer {
  public:
    RingBuffer(int size);
    ~RingBuffer();

    int count() {return (size + end - start) % size;}

    void write(char *data, int bytes) {
      // some work that uses only buffer and end
      end = (end + bytes) % size;
    }

    void read(char *data, int bytes) {
      // some work that uses only buffer and start
      start = (start + bytes) % size;
    }

  private:
    char *buffer;
    const int size;
    int start, end;
};
这是问题所在。假设低优先级进程有一个oracle,告诉它确切地需要读取多少数据,因此永不调用
count()
。然后(除非我丢失了某些东西)没有并发问题。但是,一旦低优先级线程需要调用
count()
(高优先级线程可能也要调用它以检查缓冲区是否太满),则有可能在count()中进行数学运算或更新为最终不是原子的,引入了错误。 我可以在开始和结束的访问周围放置一个互斥锁,但是如果高优先级线程必须等待低优先级线程获取的锁,则会导致优先级反转。 我也许可以使用原子操作来解决一些问题,但是我不知道提供这些功能的一个不错的跨平台库。 是否有标准的环形缓冲区设计可以避免这些问题?     
已邀请:
只要您遵循以下准则,您拥有的一切就可以了: 只有一个线程可以写。 只有一个线程可以读取。 对
start
end
的更新和访问都是原子的。这可能是自动的,例如Microsoft声明:   简单的读写   正确对齐的32位变量是   原子操作。换句话说,你   不会只剩下一部分   更新的变量;所有位都是   以原子方式更新。 您可以考虑到即使您获得了价值,ѭ5可能已经过时了。在阅读线程中,ѭ5将返回您可以依靠的最小计数;因为写线程“ 5”将返回最大计数,而真实计数可能会更低。     
Boost提供了一个循环缓冲区,但是它不是线程安全的。不幸的是,我不知道这是什么实现。 即将到来的C ++标准将原子操作添加到了标准库中,因此将来将可以使用它们,但是大多数实现尚不支持它们。 我看不到任何跨平台的解决方案都能在两个线程都向其中写入5时保持理智,除非您实现了锁定。 通常,您可能会使用消息传递系统并强制低优先级线程请求高优先级线程进行更新或类似的操作。例如,如果低优先级线程消耗15个字节,则应要求高优先级线程将计数减少15。 本质上,您将限制对高优先级线程的“写”访问,并且仅允许低优先级线程进行读取。这样,您可以避免所有锁定,并且高优先级线程将不必担心等待低级线程完成写操作,从而使高优先级线程真正成为高优先级。     
boost::interprocess
boost/interprocess/detail/atomic.hpp
中提供跨平台原子功能     

要回复问题请先登录注册