避免数据竞争的核心是遵循互斥或无共享原则:用mutex保护共享可变状态,用atomic替代简单变量,用thread_local或不可变数据消除共享,用condition_variable/future等高级原语协作。

避免数据竞争的核心是确保多个线程对共享数据的访问满足“互斥”或“无共享”原则——要么不让它们同时读写,要么干脆不共享可变数据。
用互斥锁保护共享可变状态
最直接的方式是用 std::mutex(或 std::shared_mutex)包裹临界区。注意:锁必须覆盖所有访问该数据的路径,包括读和写;且要避免死锁、忘记解锁、锁粒度太粗等问题。
- 优先使用 std::lock_guard 或 std::unique_lock 实现 RAII 自动加锁/解锁,别手动调
lock()/unlock() - 多个互斥量一起加锁时,统一按地址顺序或使用 std::scoped_lock 防止死锁
- 不要在持有锁时调用可能阻塞或调用未知第三方代码的函数(比如 I/O、回调、虚函数)
用原子操作替代简单共享变量
对单个内置类型(如 int、bool、指针)的读写,若只需基本同步语义(如计数器、标志位),可用 std::atomic
- 声明为 std::atomic
counter{0}; ,用counter.fetch_add(1)替代++counter - 注意内存序(memory order):默认 std::memory_order_seq_cst 最安全但稍慢;高频场景可按需降级(如
relaxed用于计数,acquire/release用于同步临界资源) - 原子操作不能替代锁来保护多步逻辑(例如“先检查再修改”的复合操作),此时仍需互斥量或 std::atomic
::compare_exchange_weak
消除共享:用线程局部存储或不可变数据
不共享,就无竞争。这是最彻底的方案。
标签: 工具 ai c++ 异步任务 数据访问 无锁 red 有锁
还木有评论哦,快来抢沙发吧~