dimanche 1 janvier 2023

condition_variable::wait_until passes through unexpectedly g++ (9.4.0)

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;

}
  • There does not appear to be a difference in the compiled wait_until.
  • In both programs, there is ultimately a call to 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.

Update

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.

Aucun commentaire:

Enregistrer un commentaire