我有類似這樣的一個問題:condition_variable :: wait_for和wait_until使用chrono :: steady_clock但在PC休眠時跳過持續時間?
Are there any STL functions that wait that use wallclock time instead of "machine awake" time?
我寫了下面一個簡單的測試程序。其輸出作爲main()函數之後的註釋附加。
#include <iostream>
#include <atomic>
#include <condition_variable>
#include <thread>
#include <chrono>
namespace Test1 {
std::condition_variable cv1;
std::mutex cv_m1;
std::atomic<int> i1{ 0 };
void WaitForTest(int durationSeconds)
{
std::unique_lock<std::mutex> lk(cv_m1);
if (cv1.wait_for(lk, std::chrono::seconds(durationSeconds), []() {return i1 > 0;}))
std::cerr << "Thread WaitForTest finished waiting. i == " << i1 << '\n';
else
std::cerr << "Thread WaitForTest timed out. i == " << i1 << '\n';
}
}
namespace Test2 {
std::condition_variable cv1;
std::mutex cv_m1;
std::atomic<int> i1{ 0 };
void WaitUntilTest(int durationSeconds)
{
std::unique_lock<std::mutex> lk(cv_m1);
if (cv1.wait_until(lk, std::chrono::steady_clock::now() + std::chrono::seconds(durationSeconds), []() {return i1 > 0;}))
std::cerr << "Thread WaitUntilTest finished waiting. i == " << i1 << '\n';
else
std::cerr << "Thread WaitUntilTest timed out. i == " << i1 << '\n';
}
}
void DisplayCounter()
{
for (;;)
{
std::cout << std::chrono::steady_clock::now().time_since_epoch().count() << '\t';
std::cout << std::chrono::system_clock::now().time_since_epoch().count() << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::thread t0(DisplayCounter);
std::thread t1(Test1::WaitForTest, 20);
std::thread t2(Test2::WaitUntilTest, 20);
t1.join();
t2.join();
t0.join();
}
/*
4823241754127 14507388260401666
4824249305761 14507388270471228
4825256111840 14507388280536768
4826265075762 14507388290623794
4827272062892 14507388300690885
4828278976945 14507388310756954
4829285939442 14507388320824912
4830292731972 14507388330889902
4831301325579 14507388340950061
4832325019583 14507388351168172
4833328913228 14507388361252847
4834344668038 14507388371893418
4835526960329 14507388383183227 // Put PC to sleep for several minutes here.
5239334902724 14507392428113950
5241228987291 14507392440270719
5242391680803 14507392453061650
5243860130948 14507392467439058
5245178576003 14507392479499693
Thread WaitUntilTest timed out. i == 5246249606694Thread WaitForTest timed out. i == 14507392493628356
0
0
5247878128997 14507392507329527
5249076101379 14507392518267779
5250080155548 14507392528308436
*/
/*
6901440131309 14507409048031904
6902447235446 14507409058098709
6903453988153 14507409068147687
6904456435024 14507409078169356
6905459314613 14507409088221283
6906465590262 14507409098284729
6907472642259 14507409108354858
6908479366227 14507409118421845
6909485420590 14507409128482293
6910492000867 14507409138524952
6911494460464 14507409148547279
6912496188054 14507409158571820
6913503297528 14507409168712603
6914518360974 14507409178777637
6915520958927 14507409188797529
6916522928740 14507409273645140 // Put PC to sleep for several seconds here.
6925151268349 14507409284698259
6926154791268 14507409294728122
6927189995828 14507409306269589Thread WaitForTest timed out. i ==
Thread WaitUntilTest timed out. i == 0
0
6928477053195 14507409318749386
6929719714225 14507409331272114
6930891244389 14507409342498796
*/
在網頁http://www.cplusplus.com/reference/condition_variable/condition_variable/wait_for/
它說
它的行爲就好像是執行: 回報wait_until(LCK,計時:: steady_clock ::現在()+ REL_TIME,標準: :移動(預解碼值));
輸出顯示,即使PC睡着了,steady_clock也會提前。
問:爲什麼condition_variable :: wait_until只計算PC喚醒時的持續時間?