C++11: yield() vs sleep_for()

 

      在写入Microsoft专用C++代码时,spinlocking时使用Sleep(1)比Sleep(0)好,是因为Sleep(0)将使用更多的CPU时间,而且Sleep(0)只有在有另外一个等于-priority线程等待运行。

      然而,使用C++ 11线程库,没有太多关于std :: this_thread :: yield()与std :: this_thread :: sleep_for(至少可以找到)的文档std :: chrono :: milliseconds(1));第二个肯定是更冗长,但是它们对于自旋锁同样有效,还是会受到潜在的同样的影响睡眠(0)与睡眠(1)的感染?

      一个示例循环,其中std :: this_thread :: yield()或std :: this_thread :: sleep_for(std :: chrono :: milliseconds(1))将是可以接受的:

void SpinLock( const bool& bSomeCondition )
{
    // Wait for some condition to be satisfied
    while( !bSomeCondition )
    {
         /*Either std::this_thread::yield() or 
           std::this_thread::sleep_for( std::chrono::milliseconds(1) ) 
           is acceptable here.*/
    }

    // Do something!
}

最佳答案:

      > yield将放弃当前时间片,并将线程重新插入到调度队列中。线程再次执行之前到期的时间通常完全取决于调度程序。请注意,标准将收益率称为重新安排的机会。所以一个实现是完全可以自由地从产量立即返回,如果它的愿望。收益率将永远不会将线程标记为非活动状态,因此产生收益的线程将始终在一个核心上产生100%的负载。如果没有其他线程已经准备就绪,则在重新安排计划之前,您最多可能会丢失当前时间片的剩余部分。
      > sleep_ *将阻塞线程至少要求的时间量。一个实现可能会将sleep_for(0)转换成yield。另一方面,sleep_for(1)会让你的线程暂停。线程首先转到不同的睡眠线程队列,而不是返回到调度队列。只有在所请求的时间量过去之后,调度器才会考虑将线程重新插入到调度队列中。小睡眠所产生的负担仍将非常高。如果所请求的休眠时间小于系统时间片,您可以期望该线程只能跳过一次(即,一个产量释放活动时间片,然后跳过该时间片),这仍然会导致cpu加载在一个核心上接近或甚至等于100%。

另外:

  C++11 标准库提供了yield()和sleep_for()两个方法。

    (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周期里再参与CPU调度。这是主动放弃CPU的方法接口。

    (2)std::sleep_for():线程调用该方法时,同样会让出CPU,并且休眠一段时间,从而让其他线程有机会运行。等到休眠结束时,才参与CPU调度。这也是主动放弃CPU的方法。

    两者的不同很明显:

   1、yield()方法让出CPU的时间是不确定的,并且以CPU调度时间片为单位。而sleep_for()让出CPU的时间是固定的。

    2、yield()的实现依赖于操作系统CPU调度策略,在不同的操作系统或者同一个操作系统的不同调度策略下,表现也可能是不同的。

 

https://stackoverflow.com/questions/17325888/c11-thread-waiting-behaviour-stdthis-threadyield-vs-stdthis-thread

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值