15 July 2023

C++ 核心指南目录

“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 然后, hnnh 进行交换。新的 h 成了 nnh 。这时候,线程又切换回来, nh 和老的 h 进行交换,这时候, h 指向的链表就丢失了。

例外

只要你使用顺序的内存模型( memory_order_seq_cst ),你就可以简单安全地使用原子变量。

注意

高层的并行机制,如线程和互斥锁是用无锁编程实现的。

其他选项

使用别人实现的无锁数据结构。