[C++] 多线程编程-thread::yield()-sleep_for()
文章目录
- std::this_thread::yield()
- 和std::this_thread::sleep_for的不同
- Reference
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// }}
}
- 如果条件不满足时,程序会立刻返回,然后立即与其他线程竞争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 bitauto 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())) {// successh = 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