翻看代码的时候,std::this_thread::yield() 猛的引入眼帘,C11里面的语法糖,用了不少,yield还是第一次看到,以前都没注意。

没查手册,首先想到的是不是和异步变成相关,yieldboost库的协程实现里面用到了这个单词,这里肯定和协程没关系,控制逻辑和普通线程相关。

文档

yield

此函数的准确性为依赖于实现,特别是使用中的 OS 调度器机制和系统状态。例如,先进先出实时调度器( Linux 的 SCHED_FIFO )将悬挂当前线程并将它放到准备运行的同优先级线程的队列尾(而若无其他线程在同优先级,则 yield 无效果)

sleep_for

阻塞当前线程执行,至少经过指定的 sleep_duration 此函数可能阻塞长于 sleep_duration ,因为调度或资源争议延迟 标准库建议用稳定时钟度量时长。若实现用系统时间代替,则等待时间亦可能对时钟调节敏感

分析

两个函数都是让当前线程不再占用线程,执行的效果按照平台情况而定?看到这里依旧有点云里雾里的,运行代码看看执行效果

ThinkPad 笔记本(visual studio 社区版2022)、腾讯云S2标准服务器(gcc8.5)

运行平台 函数 第一次/us 第二次/us 第三次/us
Windows sleep_for 9872 1884 11302
Windows yield 119 100 100
Linux sleep_for 171 168 167
Linux yield 101 102 101

从运行结果不难理解,由于操作系统实现的不同,高精度的休眠时,sleep_for稳定性差异巨大,如果想要高精度的休眠,使用yield更加合适

时间精度提升到ms时,两者差异并不明显

#include <iostream>
#include <chrono>
#include <thread>
 
// 建议其他线程运行一小段时间的“忙睡眠”
void little_sleep(std::chrono::microseconds us)
{
    auto start = std::chrono::high_resolution_clock::now();
    auto end = start + us;
    do {
        std::this_thread::yield();
    } while (std::chrono::high_resolution_clock::now() < end);
}
 
int main()
{
    auto start = std::chrono::high_resolution_clock::now();
 
    little_sleep(std::chrono::microseconds(100));
    std::this_thread::sleep_for(std::chrono::microseconds(100));
 
    auto elapsed = std::chrono::high_resolution_clock::now() - start;
    std::cout << "waited for "
              << std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()
              << " microseconds\n";
}

参考