C11: sleep for vs yield

コードを眺めていると、std::this_thread::yield() が突然視線を集めました。C11 の構文糖で、これほど多く使われていたのは初めてです。yield を以前は目にすることはありませんでした。

マニュアルを確認せず、まず思い浮かべたのは、それが非同期処理と関連しているのではないかということでした。yield は boost 協程の実装の中に見られる単語であり、ここでは非同期処理とは関係ありません。制御ロジックは通常のスレッドに関連しています。

ドキュメント

yield

この関数の正確性は、実装に依存し、特に使用されている OS のスケジューラメカニズムとシステムの状態に依存します。例えば、先入れ先出しリアルタイムスケジューラ(Linux の SCHED_FIFO)が現在のスレッドをサスペンドし、それを実行可能な同優先度のスレッドのキューの末尾に置く(同優先度で他のスレッドがない場合、yield は効果がない)といった具合です。

sleep_for

現在のスレッドの実行をブロックし、指定された sleep_duration 分間少なくとも停止します。 この関数は、スケジューリングやリソース競合による遅延のため、sleep_duration より長くブロックされる可能性があります。 標準ライブラリでは、安定したクロックを使用して時間を測定することをお勧めします。システム時間で実装する場合は、待機時間がクロック調整に敏感になる可能性があることに注意してください。

分析

両方の関数は、現在のスレッドがスレッドを占有しないようにし、実行効果はプラットフォームによって異なる可能性があります。ここまでの内容でまだ少し理解が曖昧ですが、コードを実行して結果を確認してみましょう。

ThinkPad ノートパソコン(Visual Studio Community 2022)、腾讯云 S2 標準サーバー(gcc8.5)

分析

実行プラットフォーム 関数 初回/us 二次/us 三次/us
Windows sleep_for 9872 1884 11302

分析

実行プラットフォーム 関数 初回/US 二回目/US 三回目/US

分析

実行プラットフォーム 関数 初回/us 二回/us 三回/us
Linux sleep_for 171 168 167

分析

実行プラットフォーム 関数 初回/us 二次/us 三次/us
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";
}

参照

Licensed under CC BY-NC-SA 4.0
最終更新 2025年06月02日 20:54
金融ITプログラマーのいじくり回しと日常のつぶやき
Hugo で構築されています。
テーマ StackJimmy によって設計されています。