C++11標準ライブラリの絶対時刻によるタイムアウト付き待機処理(xxx_until
系関数)を常に意図通り動作させるには、クロックとしてstd::chrono::system_clock
ではなくstd::chrono::steady_clock
を利用する*1。
下記コードにおいてsystem_clock::is_steady == false
の場合、タイムアウト時刻に達するより前にシステム時刻調整が行われると、本来意図していたであろう「(A)時点の3分後にタイムアウト」とは異なる結果になる。
auto expires = std::chrono::system_clock::now() + std::chrono::minutes(3); // (A) //... std::this_thread::sleep_until(expires); // (B)
例えば(A)時点でのシステム時刻が 12:00 であった場合、(B)時点でのシステム時刻が 12:03 を超えるまでタイムアウト付き待機処理が行われる。(A)−(B)間にシステム時刻調整により -1:00(1時間時計を巻き戻す)された場合、結果として実時間で 1:03 の待機処理が行われる。詳細はN3337 30.2.4/p4を参照。
N3337 20.11.7.1/p1, 20.11.7.2/p1より一部引用。
1 Objects of class
system_clock
represent wall clock time from the system-wide realtime clock.class system_clock { public: static const bool is_steady = unspecified; //... };
1 Objects of class
steady_clock
represent clocks for which values oftime_point
never decrease as physical time advances and for which values oftime_point
advance at a steady rate relative to real time. That is, the clock may not be adjusted.class steady_clock { public: static const bool is_steady = true; //... };
関連URL