如何在std :: atomic <T>上实现一个简单的自旋锁,以便编译器不会优化它?

Jak*_*old 1 c++ optimization multithreading c++11

我一直在使用非常简单的方法来使用标准C++ 11/14来锁定线程,目前我最终使用了这样的东西

std::atomic<bool> setup_ready(false);

{
  // thread 1
  while (!setup_ready.load()) std::this_thread::yield();

  // do something
}

{
  // thread 2
  // perform some setup
  setup_ready.store(true);
}
Run Code Online (Sandbox Code Playgroud)

有什么东西阻止编译器优化this_thread::yield()调用,反过来整个循环?

如果我完全取消收益并且只是想忙着这样等待怎么办?是否存在一种跨平台方法来阻止编译器优化循环?或者,当在原子上循环时,标准是否会阻止它?

{
  // thread 1
  while (!setup_ready.load()) ;

  // do something
}
Run Code Online (Sandbox Code Playgroud)

我想出的唯一解决方案是在混合中添加一个volatile变量,但我不确定这是不是最好的方法.我也尝试检查关于原子的标准,但我没有找到关于编译器优化的细节的许多细节.

Mat*_*ans 7

不允许编译器优化,this_thread::yield()除非它可以确定它没有副作用 - 它不能,因为它不是.

原子加载操作无法优化,因为它包含一个内存屏障,并且专门定义为获取其他线程所做的修改.

  • 如果它是NOP,那么它是否被优化并不重要.它仍然必须运行循环来执行原子加载 (4认同)