C++ 并发与多线程:高级进阶
\n\n现代应用程序要求极致性能,而 C++ 中的多线程是实现这一目标的关键工具之一。然而,基本机制(如 std::thread、std::mutex)常常导致死锁、数据竞争和效率降低。本文将探讨 C++ 中并发编程的高级技术:从原子操作到无锁数据结构,再到异步任务。
\n\n1. 原子操作与内存序
\n\n经典的互斥锁是一种重量级机制。对于简单的计数器或标志,最好使用 std::atomic。它保证无锁的读/写原子性。然而,在高级层面,理解 内存序(C++ 内存模型,定义了线程间变更的可见性)至关重要。
主要的内存序类型:
\n- \n
memory_order_relaxed— 最小保证,仅保证原子性。 \n memory_order_consume— 很少使用,依赖于数据。 \n memory_order_acquire— 此操作之后的所有后续读/写不能被重排到此操作之前。 \n memory_order_release— 此操作之前的所有写入在此操作之后对其他线程可见。 \n memory_order_acq_rel— acquire 和 release 的组合。 \n memory_order_seq_cst— 最严格,全局顺序一致性(默认)。 \n
使用示例:
\n#include <atomic>\n#include <thread>\n#include <cassert>\n\nstd::atomic<bool> ready{false};\nint data = 0;\n\nvoid producer() {\n data = 42; // 写入数据\n ready.store(true, std::memory_order_release); // 发布标志\n}\n\nvoid consumer() {\n while (!ready.load(std::memory_order_acquire)) // 等待标志\n ;\n assert(data == 42); // 保证看到 data == 42\n}\n\nint main() {\n std::thread t1(producer);\n std::thread t2(consumer);\n t1.join();\n t2.join();\n return 0;\n}\n\n这里,release 和 acquire 保证 data 的写入发生在标志设置之前,而读取发生在标志设置之后。这比互斥锁更快。
2. 无锁数据结构
\n\n无锁算法通过使用原子操作和 CAS(比较并交换)来避免锁。经典示例是基于单链表的无锁栈。
\n\n无锁栈的实现:
\n#include <atomic>\n#include <memory>\n\ntemplate<typename T>\nclass LockFreeStack {\nprivate:\n struct Node {\n T data;\n Node* next;\n Node(const T& val) : data(val), next(nullptr) {}\n };\n std::atomic<Node*> head{nullptr};\n\npublic:\n void push(const T& val) {\n Node* new_node = new Node(val);\n new_node->next = head.load(std::memory_order_relaxed);\n while (!head.compare_exchange_weak(\n new_node->next, new_node,\n std::memory_order_release,\n std::memory_order_relaxed)) {\n // 循环直到 CAS 成功\n }\n }\n\n bool pop(T& result) {\n Node* old_head = head.load(std::memory_order_relaxed);\n while (old_head != nullptr &&\n !head.compare_exchange_weak(\n old_head, old_head->next,\n std::memory_order_acquire,\n std::memory_order_relaxed)) {\n // 等待\n }\n if (old_head == nullptr) return false;\n result = old_head->data;\n // 注意:在实际代码中,需要垃圾回收或 hazard pointers\n delete old_head;\n return true;\n }\n};\n\n重要说明:
\n- \n