在 C++11 下编译失败的原因是 compare_exchange_weak()
函数需要使用带有返回值的版本,即 compare_exchange_weak(expected, desired)
。修改代码如下:
#include <atomic>
#include <cstddef>
#include <memory>
template<typename T>
class LockFreeQueue {
public:
LockFreeQueue() : head_(new Node), tail_(head_.load()) {}
void push(const T &item) {
std::unique_ptr<Node> new_node(new Node);
new_node->data = item;
while (true) {
Node *tail = tail_.load();
Node *next = tail->next.load();
if (tail == tail_.load()) {
if (next == nullptr) {
if (tail->next.compare_exchange_weak(next, new_node.get())) {
tail_.compare_exchange_weak(tail, new_node.get());
new_node.release();
return;
}
} else {
tail_.compare_exchange_weak(tail, next);
}
}
}
}
bool try_pop(T &item) {
while (true) {
Node *head = head_.load();
Node *tail = tail_.load();
Node *next = head->next.load();
if (head == head_.load()) {
if (head == tail) {
if (next == nullptr) {
return false;
}
tail_.compare_exchange_weak(tail, next);
} else {
item = next->data;
if (head_.compare_exchange_weak(head, next)) {
// delete head; 不需要手动释放内存,unique_ptr 会自动释放
return true;
}
}
}
}
}
private:
struct Node {
T data;
std::atomic<Node *> next{nullptr};
};
std::atomic<Node *> head_;
std::atomic<Node *> tail_;
};