【问题标题】:Understanding C++ memory model : Different values on different runs了解 C++ 内存模型:不同运行的不同值
【发布时间】:2015-10-08 05:34:19
【问题描述】:

下面的代码有什么问题?我预计消费者 1 和消费者 2 会产生 10,但有时我会看到 -1。

#include <thread>   
#include <atomic>
#include <cassert>
#include <string>

std::atomic<int> global;
void producer()
{
   global.store(10, std::memory_order_release);
}

void consumer1()
{
   int a = global.load(std::memory_order_acquire);
   printf("a in consumer1 %d\n", a);
}

void consumer2()
{
   int a = global.load(std::memory_order_acquire);
   printf("a in consumer2 %d\n", a);
}

int main()
{
    global.store(-1, std::memory_order_seq_cst);
    std::thread t1(producer);
    std::thread t2(consumer1);
    std::thread t3(consumer2);
    t1.join(); t2.join(); t3.join();
}

我明白了 a in consumer1 10 a in consumer2 10a in consumer1 -1 a in consumer2 10

如果我理解正确,memory_order_acquire 的线程总是与memory_order_release 的线程同步。我错了吗? 我在 x86-64 位机器上运行。我正在编译 g++ file.cpp -pthread -std=c++11

【问题讨论】:

  • 在你的例子中,我从来没有得到-1,总是“a in consumer1 10 a in consumer2 10”你能睡一觉以得到你发布的“错误”结果吗?
  • 运行多次。我运行了至少 20 次,其中一次运行显示 -1。
  • 我已经完成了 100 次测试。
  • 但我确实看到这是直接从我的终端粘贴的输出。 madhura@linux64 ~ ./a.out a in consumer2 10 a in consumer1 10 madhura@linux64 ~ ./a.out a in consumer1 -1 a in consumer2 10
  • “同步于”表示如果 global 已被生产者更新,消费者将看到更新。可能通过强制缓存更新或任何需要的方式。这并不意味着如果消费者跑在生产者前面,它就会停下来等待。

标签: c++ multithreading c++11 parallel-processing atomic


【解决方案1】:

原子变量有一个非常好的属性,即读取的值是之前写入的值。使用释放/获取语义,它甚至是写入的 last 值。

在这种情况下,您有 2 次写入和两次读取。只有 -1 的写入是排序的——在读取之前,10 的写入是不排序的。因此,任何一个值都可能是最后写入的。保证您读取 -1 或 10 而不是垃圾。

【讨论】:

  • "只有 -1 的写入是先排序的-在读取之前,10 的写入是不排序的"我没明白,你说的术语 Sequence-before 是什么意思?
  • @username_4567:这就是 C++11 在多线程程序中定义执行顺序的方式。如果两个操作相对于彼此进行排序,那么先排序的操作肯定会首先发生。未排序的操作可以以任何顺序发生,可能同时发生。
【解决方案2】:

如果你在之前添加一个睡眠

global.store(10, std::memory_order_release);

那么您可以始终观察到 -1。

关键是 std::memory_order 不是类似信号量的同步,而是一个更微妙的事情。见cppreference

【讨论】:

    猜你喜欢
    • 2020-10-10
    • 2022-01-04
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2020-02-06
    • 2010-12-26
    相关资源
    最近更新 更多