C++中所有写操作完成后无需持互斥锁访问数据是否安全?
问题解答
示例代码的安全性
你的示例代码是完全安全的,无需在最后一行访问arr时持有互斥锁。
原因在于std::thread::join()本身具备明确的线程同步语义:当主线程调用join()并等待子线程结束后,子线程中所有完成的内存写操作(包括那些通过互斥锁保护的对arr的修改),都会被同步到主线程的内存视图中。主线程此时看到的arr一定是所有子线程修改完成后的最终状态,不会出现缓存不一致的问题,最后一行的访问行为不存在未定义行为。
无需持锁即可访问数据的场景
满足以下任意一种情况时,你可以不用持锁访问共享数据:
- 所有写操作已完全结束,且无后续写操作:确保没有任何线程会再修改该数据,同时通过可靠的同步机制(比如
join、条件变量的wait/notify、原子操作的内存屏障)让当前线程能看到所有写操作的最终结果。你的示例就属于这种情况。 - 数据仅被只读访问:所有线程对该数据都只执行读操作,没有任何写操作,自然不会有数据竞争问题。
- 使用原子类型存储数据:比如用
std::atomic<int>替代普通int,原子操作本身提供了内存可见性保障和操作原子性,无需额外互斥锁即可安全读写。
需要注意的是,如果在join之后仍有其他线程可能异步修改arr,那主线程访问时依旧需要持有互斥锁,否则会引发数据竞争。
内容的提问来源于stack exchange,提问作者4-bit
相关产品推荐
相关产品推荐

