本文介绍: 介绍了this_thread::yield和this_thread::sleep_for的使用场景和区别。

std::this_thread::yield()

应用场景:当该线程条件不满足,处于等待资源的状态的时候,我们希望他等待的时候不浪费CPU资源,那么应该这么处理。 (写线程池的时候,需要考虑的情况)

  • std::this_thread::yield() 的目的是避免一个线程(that should be used in a case where you are in a busy waiting state)频繁与其他线程争抢CPU时间片, 从而导致多线程处理性能下降.
    将停止当前线程的执行并优先考虑其他进程/线程(如果队列中还有其他进程/线程等待)。 线程的执行不会停止。(它只是释放CPU) ,具体过程就是将线程放到同级执行队列的后面,重新等待调度。例如,先进先出实时调度程序(Linux 中的 SCHED_FIFO)会挂起当前线程,并将其放在准备运行的相同优先级线程队列的后面(如果没有其他线程)线程具有相同的优先级,yield 没有效果)。
void function()
{
    while (True)
    {
        if (!HasTask())
        {
        		 // we should use this_thread::yield() here.
            return;
        }
       // else
       // {
       //     // do work
       // }
    }
}
  • 根据上面代码所示,如果条件不满足时,程序return会立刻返回,然后立即与其他线程竞争CPU时间片, 结果就是此线程频繁的与其他线程争抢CPU时间片, 从而影响程序性能。而使用 std::this_thread::yield() 后, 就相当于”当前线程”检查条件不成功后, 将其未使用完的”CPU时间片”分享给其他线程使用, 等到其他线程用完后, 再和其他线程一起竞争(具体实现就是将线程放在队列后面,等待重新调度)。

源码参照: https://github.com/facebook/folly/blob/a3e8938068d849312e828da0ebb39973696cdcca/folly/synchronization/LifoSem.h#L427

/// Prevents blocking on this semaphore, causing all blocking wait()
/// calls to throw ShutdownSemError.  Both currently blocked wait() and
/// future calls to wait() for which tryWait() would return false will
/// cause an exception.  Calls to wait() for which the matching post()
/// has already occurred will proceed normally.
void shutdown() {
    // first set the shutdown bit
    auto h = head_->load(std::memory_order_acquire);
    while (!h.isShutdown()) {
      if (h.isLocked()) {
        std::this_thread::yield();
        h = head_->load(std::memory_order_acquire);
        continue;
      }

      if (head_->compare_exchange_strong(h, h.withShutdown())) {
        // success
        h = h.withShutdown();
        break;
      }
      // compare_exchange_strong rereads h, retry
    }
    ...
}

和std::this_thread::sleep_for的不同

  • sleep_for: 线程调用该方法时,同样会让出CPU,并且休眠一段时间,从而让其他线程有机会运行。 等到休眠结束时,才参与CPU调度; 同时,yield也会释放cpu;并将线程放到同级别的线程队列的后面,等待执行,不会阻塞或者中断线程的执行。所以yield()方法让出CPU的时间是不确定的,并且以CPU调度时间片为单位。
  • sleep_for是堵塞线程,yield是重排线程时间片占用。
  • void sleep_for( const std::chrono::duration<Rep, Period>& sleep_duration ); 阻塞至少sleep_duration时间,由于调度或资源争用延迟,该函数可能会阻塞超过 sleep_duration 的时间。

Reference

  • https://en.cppreference.com/w/cpp/thread/yield
  • https://blog.csdn.net/liuhhaiffeng/article/details/52604052
  • https://stackoverflow.com/questions/11048946/stdthis-threadyield-vs-stdthis-threadsleep-for
  • https://blog.csdn.net/liuhhaiffeng/article/details/52604052
  • https://github.com/facebook/folly.git

原文地址:https://blog.csdn.net/mingshili/article/details/135611772

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_60865.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注