来自Boost.Atomic示例崩溃的无等待队列

时间:2013-02-10 20:43:18

标签: c++ boost concurrency c++11 atomic

我正在寻找使用atomics的无等待队列的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;
}

}

Example at boost official site

我用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.Atomic或原子的MSVC实现中的错误吗?

1 个答案:

答案 0 :(得分:1)

它看起来像是MSVC实现中的一个错误。断言失败,因为Order2memory_order_release。但是,正如所指出的here(与C ++标准相同)(强调我的):

  

3参数过载相当于4参数过载   使用success_order == order和failure_order == order,但if除外   order是std :: memory_order_acq_rel,然后是failure_order   std :: memory_order_acquire,如果order是std :: memory_order_release,则为   然后failure_order是std :: memory_order_relaxed

换句话说,Order2 对于您的案例中的4参数重载必须 std::memory_order_relaxed,因为您将memory_order_release作为order传递。在MSVC的实现中并非如此,这是一个错误。如果可能,请将其报告为错误。