一个读者一个编写者,int或atomic_int

hud*_*dac 1 c++ multithreading atomic memory-fences c++11

我知道这不是一个新问题,但在阅读了关于c ++ 11内存栅栏后我感到困惑;

如果我有一个读者线程和一个编写器线程.
我可以使用普通的int吗?

    int x = 0; // global
writer    reader
x = 1;    printf("%d\n", x);
Run Code Online (Sandbox Code Playgroud)

这种行为是不确定的?
我可以在读者线程中获得未定义的值吗?
或者就像使用std::atomic_uint_fast32_tstd::atomic<int>?因此,价值将会到达读者线程 - 最终.

    std::atomic<int x = 0; // global
writer                                    reader
x.store(1, std::memory_order_relaxed);    printf("%d\n", x.load(std::memory_order_relaxed));
Run Code Online (Sandbox Code Playgroud)

答案取决于我使用的平台吗?(例如x86),所以加载/存储普通int是一条CPU指令?

如果两种行为都相似,那么我是否应该期望两种类型的性能相同?

Chr*_*son 5

简而言之,永远不要使用普通模式int在多线程环境中共享.

问题不仅在于您的CPU,还在于编译器的优化器.gcc可以(并将)优化代码,如:

while(i == 1) {}进入if(i==1) { while(1) {} }.一旦检查了变量一次,它就不必再次重新加载该值.这与所有其他可能的问题是分开的,即看到半写值(实际上通常不会出现在x86整数上).

测量效果atomic非常困难 - 在很多情况下,CPU可以高度优化访问,而在其他情况下,它们要慢得多.你真的必须在实践中进行基准测试.

  • "问题不仅仅是**你的CPU" (2认同)
  • 是的,如果`i`是一个普通的整数.因为在一个线程中读取"int"并将其写入另一个线程中是未定义的行为.如果编译器必须假设变量可以随时写入其他线程,那么它们将有效地编译所有变量,如`atomic`变量,这会使代码变慢. (2认同)