#include <iostream>
#include <atomic>
#include <array>
#include <thread>
template <typename T>
struct node {
T value;
node* next{nullptr};
};
typedef node<int> node_type;
std::atomic<node_type*> _begin;
node_type* get() {
node_type* b = _begin;
while (!_begin.compare_exchange_weak(b, b->next))
;
return b;
}
void give(node_type* v) {
v->next = _begin;
while (!_begin.compare_exchange_weak(v->next, v))
;
}
void get_and_give() {
for (int i = 0; i < 1000000; ++i) {
auto n = get();
give(n);
}
}
int main(int argc, const char * argv[])
{
std::array<node_type, 4> _nodes;
for (auto & i : _nodes)
give(&i);
std::thread t1(get_and_give);
std::thread t2(get_and_give);
std::thread t3(get_and_give);
get_and_give();
t1.join();
t2.join();
t3.join();
return 0;
}
在get返回的值内的下一个指针上有一个竞赛(我相信)。运行get_and_give的2个线程不会发生这种情况,所以看起来它在其他线程中缺乏顺序一致性,但我所做的一切都是memory_order_seq_cst,所以我不明白这可能是一个什么问题?
任何想法!?
答案 0 :(得分:3)
我怀疑你遇到了所谓的ABA问题。
ABA问题发生在同步期间,当一个位置被读取两次,两次读取具有相同的值,并且&#34;值是相同的&#34;用于表示&#34;没有任何改变&#34;。但是,另一个线程可以在两个读取之间执行并更改值,执行其他工作,然后将值更改回来,从而欺骗第一个线程思考&#34;没有任何更改&#34;即使第二个线程确实违反了这个假设。