C11: sleep for vs yield

It was the first time I saw this, and I hadn’t noticed it before

Without checking the manual, my first thought was whether it’s related to asynchronicity. The term __INLINE_CODE_0__appears in the Boost library’s coroutine implementation, but it certainly isn’t related to coroutines here; the control logic is likely related to ordinary threads.

Document

yield

The accuracy of this function depends on the implementation, particularly the OS scheduler mechanism and system state. For example, a first-in, first-out real-time scheduler (such as Linux’s SCHED_FIFO) will suspend the current thread and place it at the tail of the queue of threads with the same priority (and yield has no effect if there are no other threads at that priority).

sleep_for

Blocks the current thread’s execution for at least the specified sleep_duration This function may block for longer than sleep_duration due to scheduling or resource contention The standard library recommends measuring duration using a stable clock. If implemented with system time, wait times may also be sensitive to clock adjustments.

Analysis

Both functions release the current thread, and their effects depend on the platform. Still a bit unclear here; let’s run the code to see the execution results.

ThinkPad laptop (Visual Studio Community 2022), Tencent Cloud S2 standard server (gcc8.5)

Runtime Platform Function First/μs Second/μs Third/μs
Windows sleep_for 9872 1884 11302
Windows yield 119 100 100
Linux sleep_for 171 168 167
Linux yield 101 102 101

Given the operating system implementation, INLINE_CODE_0__稳定性差异巨大,如果想要高精度的休眠,使用__INLINE_CODE_1 is more suitable for high-precision sleep

The difference is not significant when time accuracy is improved to INLINE_CODE_0

#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";
}

Reference

Licensed under CC BY-NC-SA 4.0
Last updated on May 28, 2025 09:47
A financial IT programmer's tinkering and daily life musings
Built with Hugo
Theme Stack designed by Jimmy