多线程编程的难点不在于创建线程,而在于如何安全地在多个线程之间共享状态。C++11 引入了一套完善的并发支持库,包括线程、互斥锁、条件变量和原子操作,为编写正确、高效的多线程程序提供了完备的工具。
线程与同步原语
std::thread 提供了基本的线程创建与管理。配合 mutex、lock_guard 和 unique_lock,可以实现基本的互斥访问:
- std::mutex:基本的互斥锁,不可递归。
- std::recursive_mutex:同一线程可以多次加锁。
- std::shared_mutex:读写锁,多个读者可同时持有,写者独占(C++17)。
原子操作与内存序
std::atomic 提供了无锁的原子操作。关键在于选择正确的内存序:
- memory_order_relaxed:只保证原子性,不保证顺序。
- memory_order_acquire/release:确保获取-释放语义。
- memory_order_seq_cst:全局顺序一致性,最安全但最慢。
无锁编程
在某些场景下,无锁数据结构可以提供比锁更高的并发性能。但编写正确的无锁代码极其困难——需要深入理解内存模型,并且要处理 ABA 问题等并发陷阱。
多线程的复杂度是指数级的,保持简单是最好的并发策略。