folly源码分析(2)- ProducerConsumerQueue.h

来源:互联网 发布:网络药品销售 编辑:程序博客网 时间:2024/05/17 16:00

无锁队列,支持一个读线程和一个写线程

设计思想:

队列预先分配,通过std::atomic类型的readIndex和writeIndex来标识读和写的位置,然后通过原子操作这两个索引,可以实现不加锁的目的

核心代码如下:

template<class...Args>  bool write(Args&&... recordArgs) {    auto const currentWrite =writeIndex_.load(std::memory_order_relaxed);    auto nextRecord =currentWrite + 1;  //因为只有一个写线程,所以这里不会冲突    if (nextRecord == size_) {      nextRecord = 0;    }         // 读写线程冲突的地方,readIndex.load确保看到写线程里的readIndex值    if (nextRecord !=readIndex_.load(std::memory_order_acquire)) {       new (&records_[currentWrite])T(std::forward<Args>(recordArgs)...);       //确保写到writeIndex里的值可以被读线程看到      writeIndex_.store(nextRecord,std::memory_order_release);      return true;    }     // queue is full    return false;  }   // move (or copy) the value at the front ofthe queue to given variable  bool read(T& record) {    auto const currentRead =readIndex_.load(std::memory_order_relaxed);     // 同上    if (currentRead ==writeIndex_.load(std::memory_order_acquire)) {      // queue is empty      return false;    }     auto nextRecord = currentRead + 1;    if (nextRecord == size_) {      nextRecord = 0;    }    record = std::move(records_[currentRead]);    records_[currentRead].~T();    readIndex_.store(nextRecord,std::memory_order_release);    return true;  }