I'm working with std::condition_variable::wait_until
in C++ and I'm using std::chrono::system_clock
and std::chrono::steady_clock
to manage the waiting time. After reading the documentation, I understand that the sleeping time should not be affected by changes in the system time when using std::chrono::steady_clock
, while it may change when using std::chrono::system_clock
.
However, my code is behaving differently: for both clock types, the waiting time is affected by the system time. Here's a minimal reproducible example:
#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <ctime>
#include <sys/time.h>
#include <condition_variable>
#include <atomic>
std::atomic<bool> flag = false;
std::condition_variable cv;
void wait_using_system_clock()
{
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::mutex mtx;
std::unique_lock lock(mtx);
cv.wait_until(lock, std::chrono::system_clock::now() + std::chrono::seconds(20), [](){return flag.load();});
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "Time difference [using system clock] = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() << "s" << std::endl;
}
void wait_using_steady_clock()
{
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::mutex mtx;
std::unique_lock lock(mtx);
cv.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::seconds(20), [](){return flag.load();});
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
std::cout << "Time difference [using steady clock] = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() << "s" << std::endl;
}
void set_system_time_forward()
{
std::this_thread::sleep_for(std::chrono::seconds(2)); // Ensure other threads has executed cv.wait_until
struct timeval tv;
gettimeofday(&tv, NULL);
tv.tv_sec += 15;
settimeofday(&tv, NULL);
}
int main()
{
std::thread t1(wait_using_system_clock);
std::thread t2(wait_using_steady_clock);
std::thread t3(set_system_time_forward);
t1.join();
t2.join();
t3.join();
return 0;
}
I execute the wait_using_system_clock
and wait_using_steady_clock
functions on different threads. Another thread is used to change the system time after 2 seconds. I expect that the function wait_using_steady_clock
should not be affected by this change and should wait for 20 seconds, but instead, both functions finish their execution in approximately 5 seconds, printing:
Time difference [using system clock] = 5s
Time difference [using steady clock] = 5s
Can anyone help me understand why this discrepancy exists between the expected and actual behavior? Is there something I'm missing in the documentation or misunderstanding about these classes?
Aucun commentaire:
Enregistrer un commentaire