Repository navigation
<condition_variable>: The actual waiting time of cv.wait_for() is longer than duration param #2173
Description
Activity
I doubt that STL implementation is wrong.
But I found a small pattern:
- If OS is idle then I got ~60000, same as your results.
- If OS has some load(for Windows 10, running VirtualBox is enough, for Windows 7 running Edge), then I got ~50000.
On Windows 10 21H1:
Same behavior on Windows 7 SP1.


Possibly related to energy saving...
https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for
This function may block for longer than timeout_duration due to scheduling or resource contention delays.
This is pretty typical for non-realtime operating systems. When you sleep, or block on something, you relinquish your time slice to the OS. Your thread will now be suspended until a time slice is available for your thread to run in, which may not correspond exactly to your timeout. Your thread could also theorically never run again, if there's always a higher priority thread that gets scheduled.
You'll notice native Windows APIs like Sleep, WaitForSingleObject, timers, WaitOnAddress, etc. all expose that same behavior.
If you really need such resolution try
timeBeginPeriod:https://docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod
It works for me:
#include <stdio.h> #include <stdlib.h> #include <thread> #include <chrono> #include <string.h> #include <condition_variable> #include <memory> #include <fstream> #include <list> #include <vector> #include <mutex> #include <windows.h> #pragma comment(lib, "Winmm.lib") std::mutex mtx; std::condition_variable point_pack_condition; using namespace std::chrono; void wait() { int i = 0; steady_clock::time_point last_time = steady_clock::now(); for (i = 0; i < 20; ++i) { { std::unique_lock<std::mutex> lock(mtx); last_time = steady_clock::now(); printf("%d\n", point_pack_condition.wait_for(lock, milliseconds(50))); printf("Delta time:%ld.\n", duration_cast<microseconds>(steady_clock::now() - last_time).count()); last_time = steady_clock::now(); } printf("Finish save %d frame to lvx file.\n", i); } } int main(int argc, const char* argv[]) { timeBeginPeriod(1); std::thread t1(wait); t1.join(); timeEndPeriod(1); getchar(); }
I generally don't recommend it unless it's a time sensitive workload, as this affects battery usage (especially if you call it at start and then just leave it there forever)
Reacted by Alex GutenievImho, even on a non-rtos OS, 10ms difference is quite a lot. But yes - I don't think there is a lot the STL can or should do about it.
Reacted by Florian RichterAlexGuteniev commented
on Sep 12, 2021 ContributorMore actionsI vote for documenting that the precision of
condition_variablewait may vary depending on OS state and leaving it as it is.I think it would be valuable to explicitly state the ballpark of what can be seen in real-life (e.g. tens of ms/OS tick length). I
wpait_for anyway doesn't guarantee any particular worst case delay (in theory it can wait for seconds, minutes, hours or days after the min delay), so " can vary depending on OS state" doesn't tell the user anything new. On the other hand, something like "We have seen 10s of ms in Benchmarks" Gives the user an Idea of what to expect in regular use and not just weird/pathological edge cases.- addeddocumentationRelated to documentation or commentsRelated to documentation or comments
on Mar 26, 2023 - changed the title
[-]<conditional_variable>: The actual waiting time of cv.wait_for() is longer than duration param[/-][+]`<condition_variable>`: The actual waiting time of `cv.wait_for()` is longer than duration param[/+]on Mar 26, 2023

Describe the bug
It is found that the time interval is longer than the duration setting while using conditional_varaiable.wait_for(). If the duration is set 50ms, the actual waiting time is about 60ms..
Test case
Expected behavior

The code tested on Ubuntu16.04 or win7 behaves as follows:
Actual behavior

On win10:
Version
Windows10
visual studio 2019
vc_tools:14.29.30133