提问者:小点点

if语句中的原子变量会保护if体吗?


例如:

#include <atomic>

std::atomic_bool atomicBool(false);
int sharedVariable = 0;

void work() {
  if (atomicBool) {
    sharedVariable++; //will this line protected by atomic variable?
  }
}

SharedVariable++;语句是否会受到AtomicBool的线程安全保护? 如果不是(作为文件的一瞥我猜不是),这是否意味着在这种情况下我仍然需要使用互斥锁?


共3个答案

匿名用户

不。

原子变量不是互斥体。

除了对自己的读写之外,它们不保护任何东西。

即使是这样,使用这种语法,变量也没有办法“知道”它被命名的作用域。

听起来,SharedVariable应该是原子级的,但是如果在实际代码中有更多的语句需要保护,那么这也是不够的。

匿名用户

不,它不会保护修改。 是的,您需要在这种情况下使用互斥体,或者使SharedVariable本身为原子。

匿名用户

正如其他答案所说,不,它没有得到任何有意义的保护。 这个答案补充的是一个具体的例子。

我假设“保护”是指您希望阻止SharedVariable陷入竞态状态,并避免随后出现未定义的行为。 为了使其有意义,我将假设您实际上在某处设置了AtomicBool

考虑到这一点,下面是一个示例场景,说明为什么原子是不够的:

  1. AtomicBool由线程%1读取。 它是true.
  2. AtomicBool由线程2读取。 它是true.
  3. 两个线程现在都尝试更改SharedVariable。 这是比赛条件!

现在假设您在if语句中设置原子变量,如下所示:

if (atomicBool) {
    atomicBool = false;
    sharedVariable++;
}

这有一个自己的竞争条件,下面是一个例子来说明它是如何发生的:

  1. AtomicBool由线程%1读取。 它是true.
  2. AtomicBool由线程2读取。 它是true.
  3. AtomicBool由线程1写入false
  4. AtomicBool由线程2写入false
  5. 两个线程现在都尝试更改SharedVariable。 这是比赛条件!

您可以使用“Compare and Change”/“Test and Set”检查来代替,这些检查是原子式的(即,检查和写入对于所有观察者来说似乎是同时发生的)。

互斥体可以帮助解决这个问题,使您想要更改的变量成为原子可以解决这个问题,但是很难说哪个更合适,以及在没有更多上下文的情况下是否会在这个过程中引入更多竞争条件。

相关问题