简体   繁体   English

c ++原子读/写误解

[英]c++ atomic read/write misunderstanding

Why program with this code sometimes prints "2" ? 为什么使用此代码编程有时会打印“2”?

int main() {
    std::atomic<int> a;
    a = 0;

    std::thread t1([&]{++a;});
    std::thread t2([&]{a++;});
    std::thread t3([&]{
        a = a.load() + 1;
    });

    t1.join();
    t2.join();
    t3.join();

    if (a != 3) {
        std::cout << "a: " << a << std::endl;
    }
}

I've thought std::atomic guarantees that all operations will be done atomically so writing here(incrementing) will use a memory barrier and we will have always 3 at the end of threads work. 我认为std::atomic保证所有操作都将以原子方式完成,因此在这里写(递增)将使用内存屏障,我们将在线程结束时始终使用3 I've explored the code and found out that the problem thread is t3 but I can't understand why it is wrong. 我已经探索了代码并发现问题线程是t3但我无法理解为什么它是错误的。

t3 , unlike the two other threads, does not perform an atomic add. 与其他两个线程不同, t3不执行原子添加。 Instead, it atomically loads a , performs the arithmetic (add 1) on a temporary , and atomically stores that new value back to a . 相反,它以原子方式加载a对临时执行算术(加1),并以原子方式将新值存储回a This overwrites a regardless of atomic operations that might have happened in between. 这将覆盖a不管有可能发生之间在原子操作的。

So you can have the following scenario: 所以你可以有以下场景:

  1. t1 or t2 atomically increment a which is now equal to 1. t1t2原子递增a ,现在等于1。
  2. t3 atomically loads 1. t3原子加载1。
  3. t1 or t2 atomically increment a which is now equal to 2. t1t2原子递增a ,现在等于2。
  4. t3 performs a non-atomic add on the previously loaded value and atomically stores back 2. t3对先前加载的值执行非原子添加并以原子方式存储回2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM