ZBLOG

#include #include #include "terra_memory_pool.h" template class LockFreeQueue { public: LockFreeQueue() : head_(new Node), tail_(head_.load()), memory_pool_(sizeof(Node) * 100) {} ~LockFreeQueue() { ...

这个队列的实现基本正确,但是有几个需要优化的地方:

1.内存池的大小应该是动态的,而不是固定的。可以在构造函数中传入一个参数作为内存池大小。

2.在pop操作时,并没有考虑队列为空的情况,应该加上判断。

3.push操作可以使用load-linked/store-conditional指令替换掉relaxed顺序,使得push操作更加高效。

修改后的代码如下:

#include <atomic>
#include <iostream>
#include "terra_memory_pool.h"

template <typename T>
class LockFreeQueue {
 public:
  explicit LockFreeQueue(const size_t& pool_size = sizeof(Node) * 100)
      : head_(new Node), tail_(head_.load()), size_{0}, capacity_{pool_size}, memory_pool_(capacity_) {}

  ~LockFreeQueue() {
    while (Node *const old_head = head_) {
      Node *next_node = old_head->value_.second;
      delete old_head;
      head_ = next_node;
    }
  }

  void push(const T &value) {
    Node *new_node;
    while (true) {
      if ((new_node = static_cast<Node *>(memory_pool_.Alloc(sizeof(Node)))) == nullptr) {
        printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
        return;
      }
      new (new_node) Node(std::make_pair(value, nullptr));
      Node *tail = tail_.load(std::memory_order_acquire);
      Node *next = tail->value_.second;

      if (tail == tail_.load(std::memory_order_relaxed)) {
        if (next == nullptr) {
          Node *empty = nullptr;
          if (tail->value_.second.compare_exchange_weak(empty, new_node)) {
            tail_.compare_exchange_strong(tail, new_node);
            size_.fetch_add(1, std::memory_order_release);
            return;
          }
        } else {
          tail_.compare_exchange_strong(tail, next);
        }
      }
    }
  }

  bool try_pop(T &value) {
    Node *old_head = head_.load(std::memory_order_relaxed);

    while (true) {
      Node *head = old_head;
      Node *tail = tail_.load(std::memory_order_acquire);
      Node *next = head->value_.second;

      if (head == head_.load(std::memory_order_relaxed)) {
        if (head == tail) {
          if (next == nullptr) {
            return false;
          }
          tail_.compare_exchange_strong(tail, next);
        } else {
          value = next->value_.first;
          if (head_.compare_exchange_weak(head, next)) {
            memory_pool_.Free(old_head, sizeof(Node));
            size_.fetch_sub(1, std::memory_order_release);
            return true;
          }
        }
      }
      old_head = head_.load(std::memory_order_relaxed);
    }
  }

  bool empty() const { return size_.load(std::memory_order_acquire) == 0; }

 private:
  struct Node {
    std::pair<T, Node *> value_;
    Node() : value_(std::make_pair(T(), nullptr)) {}
    explicit Node(const std::pair<T, Node *> &value) : value_(value) {}
  };

  std::atomic<Node *> head_;
  std::atomic<Node *> tail_;
  std::atomic<size_t> size_;
  size_t capacity_;
  terra_memory_pool memory_pool_;
};

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=1547

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?