两个线程能否写入std::atomic变量?线程安全与锁必要性咨询
std::atomic线程安全问题解答
先贴出你提供的代码:
std::atomic<int> my_integer; void Thread1() { if (condition1) { my_integer = 5; } if (my_integer == 7) { doSomething(); } } void Thread2() { if (condition2) { my_integer = 7; } }
下面逐个解答你的问题:
1. 是否需要为my_integer的读写操作添加mutex?
不需要。std::atomic的核心作用就是让单个变量的读写操作具备原子性——不会出现半写半读的撕裂情况,单个读写本身已经是线程安全的,没必要额外加mutex。
2. std::atomic变量是否已提供足够的线程安全防护?
得分情况看:
- 对于单个原子操作(比如单次赋值、单次读取),它的防护是足够的,能保证操作的原子性,而且默认内存序下读取总能拿到变量的最新值,这部分你的判断是对的。
- 但它无法保障多个原子操作组成的逻辑序列的原子性——也就是没法保证多个原子操作之间不会被其他线程插进来修改变量。
3. 当前代码是否存在竞态条件?若存在,具体是什么竞态条件?
存在竞态条件,但不是单个原子操作的问题,是逻辑流程层面的竞态:
Thread1里的两个操作(赋值5、判断是否等于7)是独立的原子操作,中间完全可能被Thread2打断。举个实际场景:
- Thread1满足condition1,把
my_integer设为5 - 线程切换到Thread2,满足condition2,把
my_integer改成7 - 切回Thread1,读取
my_integer的值为7,执行doSomething()
如果你的业务逻辑原本期望:Thread1在设完5之后,只有没被其他线程修改的情况下才判断是否等于7,那这个场景就完全不符合预期——因为Thread2的修改插在了两个操作之间。
换句话说,std::atomic只保护单个读写不被撕裂,但不保护“先赋值再判断”这个整个逻辑块的原子性。如果需要这个逻辑块不可分割,那还是得用mutex把这一段包起来。
内容的提问来源于stack exchange,提问作者EmbeddedDOOD2
相关产品推荐
相关产品推荐

