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
那可能会有问题吗?
答案 0 :(得分:6)
我编写的代码与您的代码非常相似,并衡量了在高争用条件下对yield
的调用的影响。我发现以这种方式使用yield
有利于整体系统吞吐量。
实际规范在精神上与引用的内容没有什么不同,但这里是30.3.2 [thread.thread.this]第2段和第3段的确切规范:
void this_thread::yield() noexcept;
效果:为实施提供重新安排的机会。
同步:无。
如果实现将yield
实现为无操作(例如),则这将仅影响代码的性能而不影响正确性。即使没有yield
,失败的自旋锁最终也会被抢先一步。但它也更有可能不必要地占用CPU,降低整体系统性能。
答案 1 :(得分:1)
操作系统调度程序将自动抢占自旋锁,从而无需使用此代码。当一个线程占用其时间时,操作系统将自动切换到另一个线程。这就是收益率提示的原因。例如,在Linux中的完全公平计划中,对yield的调用通常会导致不必要的上下文切换,因为调度程序试图纠正线程没有得到它的公平份额。
你试图获得一个螺旋锁不会阻挡任何东西,只有拿着螺旋锁会导致其他东西阻塞。