编写了一个支持多线程的无锁队列,但是在多线程读写的时候,遇到了奇怪的问题:
假设tail_所指节点存储的初始初始为0(以下缩略),线程1将tail_更新四次,使tail_更新为4,这时,线程2执行 std::shared_ptr<node> old_tail = std::atomic_load(&tail_);
结果old_tail仍为0,且在线程2中,tail_仍为0,请问这是为什么,如何解决?
代码如下:
template <class T>
class lock_free_queue
{
public:
lock_free_queue()
{
tail_ = std::make_shared<node>();
head_ = tail_;
}
void push(T e)
{
std::shared_ptr<node> new_node = std::make_shared<node>();
new_node->data = e;
std::shared_ptr<node> old_tail = std::atomic_load(&tail_);
do
{
while (old_tail->next) {
std::atomic_compare_exchange_weak(&tail_, &old_tail, old_tail->next);
old_tail = std::atomic_load(&tail_);
}
} while (!std::atomic_compare_exchange_weak(&old_tail->next,&new_node->next ,new_node));
std::atomic_compare_exchange_weak(&tail_, &old_tail, new_node);
}
bool pop(T &q)
{
int i=0;
std::shared_ptr<node> old_head;
std::shared_ptr<node> old_tail;
while (1)
{
old_head = std::atomic_load(&head_);
old_tail = std::atomic_load(&tail_);
if (old_head == head_)
{
if (!old_head->next)
{
if (++i < 10)
{
Sleep(0);
continue;
}
return false;
}
if (old_head == old_tail&&old_head->next)
{
std::atomic_compare_exchange_weak(&tail_, &old_tail, old_head->next);
}
if (std::atomic_compare_exchange_weak(&head_, &old_head, old_head->next))
{
q = old_head->next->data;
std::cout << q<<std::endl;
return true;
}
}
}
}
struct node
{
T data;
std::shared_ptr<node> next;
//node(const T& data_) : data(std::make_shared<T>(data_)) {}
};
private:
std::shared_ptr<node> head_;
std::shared_ptr<node> tail_;
};