在一些论坛和书籍(即C++ Concurrency in Action)中,有一个很好的多生产者/多消费者堆栈示例,在pop实现中,它们通常执行以下操作:
// head is an std::atomic<node*> variable
node *old_head = head.load();
while(old_head && !head.compare_exchange_weak(old_head, old_head->next));
...
为什么使用std::atomic<T>::compare_exchange_*会阻止 ABA 问题?让我们这么说:
- old_head->next在线程被抢占之前得到解决(就在compare_exchange_weak之前)
- 然后 BA 场景发生
- 线程恢复后head == old_head有效;在这种情况下old_head->next不会再被解析,指向一个无效的内存位置
- compare_exchange_weak将被执行,将通过,但值old_head->next仍将是旧值
然后会发生与ABA相关的问题。
我相信我错过了一些东西。我在这里想念什么?
干杯