2

我正在寻找使用原子的无等待队列的 C++ 实现,并找到了 Boost.Atomic 示例:

template<typename T>
class waitfree_queue {
public:
  struct node {
    T data;
    node * next;
  };
  void push(const T &data)
  {
    node * n = new node;
    n->data = data;
    node * stale_head = head_.load(boost::memory_order_relaxed);
    do {
      n->next = stale_head;
    } while (!head_.compare_exchange_weak(stale_head, n, boost::memory_order_release));
  }

  node * pop_all(void)
  {
    T * last = pop_all_reverse(), * first = 0;
    while(last) {
      T * tmp = last;
      last = last->next;
      tmp->next = first;
      first = tmp;
    }
    return first;
  }

  waitfree_queue() : head_(0) {}

  // alternative interface if ordering is of no importance
  node * pop_all_reverse(void)
  {
    return head_.exchange(0, boost::memory_order_consume);
  }
private:
  boost::atomic<node *> head_;
};

int main() {
// pop elements
waitfree_queue<int>::node * x = q.pop_all()
while(x) {
  X * tmp = x;
  x = x->next;
  // process tmp->data, probably delete it afterwards
  delete tmp;
}

}

boost官方网站上的示例

我已经用 std 替换了 boost 并用 MSVC 2012 编译。它崩溃并在控制台中显示下一条消息:

Assertion failed: _Order2 != memory_order_release, file c:\program files (x86)\m
icrosoft visual studio 11.0\vc\include\xxatomic, line 742

当我编译原始 boost 它运行时会崩溃。

它是 Boost.Atomic 还是 MSVC 的原子实现中的错误?

4

1 回答 1

1

它看起来像 MSVC 实现中的错误。断言失败,因为Order2is memory_order_release。但是,如此处所述与 C++ 标准相同)(强调我的):

3 参数重载等价于带有 success_order==order 和 failure_order==order 的 4 参数重载,除了如果 order 是 std::memory_order_acq_rel,则 failure_order 是 std::memory_order_acquire,并且如果 order 是 std:: memory_order_release 然后 failure_order 是 std::memory_order_relaxed

换句话说,在您的情况下Order2 必须是 std::memory_order_relaxed4 参数重载,因为您传递memory_order_releaseorder. 在 MSVC 的实现中不是这种情况,这是一个错误。如果可能,请将其报告为错误。

于 2013-02-10T21:39:21.087 回答