std :: this_thread :: yield只是一个提示有问题吗?

时间:2013-01-18 15:40:04

标签: c++ c++11 stdthread stdatomic

当有人希望用std::atomic_flag实现自旋锁互斥时,同事和我讨论了一个假设的问题,但是实现了自旋锁,而不是(true)但是作为

while(true)
{
     cnt=0;
     while (cnt<yieldAfterTries)
     {
        //try to get lock
        cnt++;
     }
     std::this_thread::yield();

     // if got lock do work and then break;
}     

基本上的想法是线程不能“长时间”阻止其他人,即使它有实时优先权,因为它会在一段时间后产生......但是当我看到 std :: yield的规格我很惊讶它是一个建议,而不是强制性的东西。

  

提供重新安排执行的实现提示   线程,允许其他线程运行。

http://en.cppreference.com/w/cpp/thread/yield

那可能会有问题吗?

2 个答案:

答案 0 :(得分:6)

我编写的代码与您的代码非常相似,并衡量了在高争用条件下对yield的调用的影响。我发现以这种方式使用yield有利于整体系统吞吐量。

实际规范在精神上与引用的内容没有什么不同,但这里是30.3.2 [thread.thread.this]第2段和第3段的确切规范:

void this_thread::yield() noexcept;
  

效果:为实施提供重新安排的机会。

     

同步:无。

如果实现将yield实现为无操作(例如),则这将仅影响代码的性能而不影响正确性。即使没有yield,失败的自旋锁最终也会被抢先一步。但它也更有可能不必要地占用CPU,降低整体系统性能。

答案 1 :(得分:1)

操作系统调度程序将自动抢占自旋锁,从而无需使用此代码。当一个线程占用其时间时,操作系统将自动切换到另一个线程。这就是收益率提示的原因。例如,在Linux中的完全公平计划中,对yield的调用通常会导致不必要的上下文切换,因为调度程序试图纠正线程没有得到它的公平份额。

你试图获得一个螺旋锁不会阻挡任何东西,只有拿着螺旋锁会导致其他东西阻塞。