CppCoreGuidelines CP.100 除非你确定需要,尽量不要用无锁编程
15 July 2023
“Don’t use lock-free programming unless you absolutely have to”
理由
容易出错,且对语言、机器架构、数据结构等知识的要求很高。
坏例子
extern atomic<Link*> head; // the shared head of a linked list Link* nh = new Link(data, nullptr); // make a link ready for insertion Link* h = head.load(); // read the shared head of the list do { if (h->data <= data) break; // if so, insert elsewhere nh->next = h; // next element is the previous head } while (!head.compare_exchange_weak(h, nh)); // write nh to head or to h
很难通过测试发现其中的 bug 。这里有所谓的 ABA 问题。比如,在 nh->next
= h
之后,线程被切换走,其他线程可能做了类似的操作, nnh->next = h
然后, h
和 nnh
进行交换。新的 h
成了 nnh
。这时候,线程又切换回来, nh
和老的 h
进行交换,这时候, h
指向的链表就丢失了。
例外
只要你使用顺序的内存模型( memory_order_seq_cst
),你就可以简单安全地使用原子变量。
注意
高层的并行机制,如线程和互斥锁是用无锁编程实现的。
其他选项
使用别人实现的无锁数据结构。