코드를 살펴보는데, INLINE_CODE_0 猛的引入眼帘,__INLINE_CODE_1__BOLD_4yield
이 처음 보는 것 같고, 예전엔 눈에 띄지 않았던 것 같아요
매뉴얼을 확인하지 않고 가장 먼저 떠오르는 것은 비동기 변환과 관련이 있는지인데, __INLINE_CODE_0__boost 라이브러리의 코루틴 구현에 이 단어가 사용되었으므로 여기서는 코루틴과는 상관없고, 제어 로직은 일반 스레드와 관련이 있는 것 같습니다
문서
yield
이 함수의 정확성은 구현에 의존하며, 특히 사용 중인 OS 스케줄러 메커니즘과 시스템 상태에 따라 달라집니다. 예를 들어, 먼저 온(FIFO) 실시간 스케줄러(Linux의 SCHED_FIFO)는 현재 스레드를 일시 중단하고 동일 우선순위의 다른 스레드가 없는 경우 큐의 맨 뒤로 배치합니다 (다른 스레드가 없으면 yield 효과 없음).
sleep_for
지정된 sleep_duration 동안 현재 스레드의 실행을 차단합니다 이 함수는 스케줄링 지연이나 리소스 충돌로 인해 sleep_duration보다 오래 블록될 수 있습니다 표준 라이브러리는 안정적인 클럭으로 시간을 측정하는 것을 권장합니다. 구현에서 시스템 시간을 사용하면 대기 시간 또한 클럭 조정에 민감할 수 있습니다.
분석
두 함수 모두 현재 스레드를 더 이상 점유하지 않도록 하는 것인데, 실행 결과는 플랫폼에 따라 다를 수 있나? 여기서도 여전히 엉망진창이다. 코드를 실행해서 결과를 확인해 보자.
ThinkPad 노트북(Visual Studio 커뮤니티 에디션 2022), 텐센트 클라우드 S2 표준 서버 (gcc8.5)
실행 플랫폼 | 함수 | 1회/μs | 2회/μs | 3회/μs |
---|---|---|---|---|
Windows | sleep_for | 9872 | 1884 | 11302 |
Windows | yield | 119 | 100 | 100 |
Linux | sleep_for | 171 | 168 | 167 |
Linux | yield | 101 | 102 | 101 |
운영체제 구현 방식에 따라 고정밀 슬립 모드에서는 __INLINE_CODE_0__稳定性差异巨大,如果想要高精度的休眠,使用__INLINE_CODE_1__이 더 적합합니다
시간 정밀도가 __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";
}