我使用新的std::atomic在C++11中生成了一个无锁(无锁)队列的简单实现,我看不出我在这里做了什么。
#include <atomic>
template<typename T>
class lockless_queue
{
public:
template<typename DataType>
struct node
{
node(const DataType& data)
: data(data), next(nullptr) {}
DataType data;
node* next;
};
lockless_queue()
: head_(nullptr) {}
void produce(const T &data)
{
node<T>* new_node = new node<T>(data);
// put the current value of head into new_node->next
new_node->next = head_.load(std::memory_order_relaxed);
// now make new_node the new head, but if the head
// is no longer what's stored in new_node->next
// (some other thread must have inserted a node just now)
// then put that new head into new_node->next and try again
while(!std::atomic_compare_exchange_weak_explicit(
&head_,
&new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed)) {}
}
node<T>* consume_all()
{
// Reset queue and return head atomically
return head_.exchange(nullptr, std::memory_order_consume);
}
private:
std::atomic<node<T>*> head_;
};
// main.cpp
#include <iostream>
int main()
{
lockless_queue<int> s;
s.produce(1);
s.produce(2);
s.produce(3);
auto head = s.consume_all();
while (head)
{
auto tmp = head->next;
std::cout << tmp->data << std::endl;
delete head;
head = tmp;
}
}我的产出是:
2
1
Segmentation fault (core dumped)我能有一些指点,看看哪里,或者指出我可能做错了什么?
谢谢!
发布于 2013-12-20 19:24:19
您正在取消tmp而不是head的引用。
while (head)
{
auto tmp = head->next;
std::cout << tmp->data << std::endl;
delete head;
head = tmp;
}应:
while (head)
{
std::cout << head->data << std::endl;
auto tmp = head->next;
delete head;
head = tmp;
}这就是为什么3没有出现在您的输出中,而Segmentation fault却出现在输出中。
发布于 2013-12-22 17:42:22
在您的代码中有另一个错误,除非您开始尝试执行并发的队列,否则不会出现。如果compare_exchange_weak_explicit失败,这意味着另一个线程设法更改了head指针,因此在您再次尝试head之前,需要将head指针的新值重新加载到new_node->next中。以下是其中的诀窍:
while(!std::atomic_compare_exchange_weak_explicit(
&head_,
&new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed)) {
new_node->next = head_.load(std::memory_order_relaxed);
}https://stackoverflow.com/questions/20710243
复制相似问题