I am trying to understand the behaviour of condition_variable::wait_until
. I have two pieces of code which I expect will wait one second and then exit. However, when I execute the programs (compiled with g++ 9.4.0, libc6 2.3.2) the first does not wait at all, whereas the second example does.
( see Update below for how to get correct behaviour in both examples )
Here's the first example which does not wait (unlike what I would expect) when executed:
// foo_passes_thru.cpp
// I compiled with `g++ foo_passes_thru.cpp`
#include <chrono>
#include <mutex>
#include <condition_variable>
std::condition_variable cv;
std::mutex m;
int main(int argc, char * argv[]) {
using namespace std::chrono_literals;
std::unique_lock<std::mutex> lk(m);
const auto now = std::chrono::high_resolution_clock::now();
cv.wait_until(lk, now + 1000ms);
return 0;
}
And the second example, which, when executed, does wait as expected:
// foo_waits_1sec.cpp
// I compiled with `g++ foo_waits_1sec.cpp -lpthread`
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <thread>
std::condition_variable cv;
std::mutex m;
int main(int argc, char * argv[]) {
using namespace std::chrono_literals;
std::thread causes_wait([]{});
// don't even need the thread to run
causes_wait.join();
std::unique_lock<std::mutex> lk(m);
const auto now = std::chrono::high_resolution_clock::now();
cv.wait_until(lk, now + 1000ms);
return 0;
}
wait_until
.pthread_cond_timedwait
. I am not sure if this is a case of unspecified behaviour or there is something incorrect in g++/STL/pthread. The documentation for pthread_cond_timedwait
didn't suggest to me that there should be differences in behaviour.
Upon posting, a related question came up that I hadn't yet seen. The behaviour that I expect is restored for the first example if I add the -pthread
compiler option. This option should be used to build both.
wait_until
is allowed to wake up spuriously. There is no guarantee that it will wait until the specified time. You need to call wait_until
in a loop, check the return value to determine whether a timeout occurred and you need some condition to check in order to decide whether the non-timeout wakeup was spurious. Alternatively you can use the second overload of wait_until
that takes the condition as a predicate and implements the loop.
Without the -pthread
option the program is single-threaded and a corresponding implementation is probably being used. In that implementation there can never be a non-spurious wakeup, so I think it is not surprising that it would be implemented to return immediately, although I have not checked the sources (of glibc or whichever libc implementation you use).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.