What is the difference between std::condition_variable and std::condition_variable_any? What is the difference between std::condition_variable and std::condition_variable_any? multithreading multithreading

What is the difference between std::condition_variable and std::condition_variable_any?


The difference is the parameter to the wait() functions. All the wait functions in std::condition_variable take a lock parameter of type std::unique_lock<std::mutex>&, whereas the wait functions for std::condition_variable_any are all templates, and take a lock parameter of type Lockable&, where Lockable is a template parameter.

This means that std::condition_variable_any can work with user-defined mutex and lock types, and with things like boost::shared_lock --- anything that has lock() and unlock() member functions.

e.g.

std::condition_variable_any cond;boost::shared_mutex m;void foo() {    boost::shared_lock<boost::shared_mutex> lk(m);    while(!some_condition()) {        cond.wait(lk);    }}

As of C++20, condition_variable_any also supports stop tokens for the new jthread class. This means that if you have a condition variable of this type, it will give up the mutex if a stop request is made, without you having to write extra polling code. This feature does not work on condition_variable for some technical reasons that were causing "races, deadlocks, and undefined behavior."

void testInterruptibleCVWait(){    bool ready = false;    std::mutex readyMutex;    std::condition_variable_any readyCV;    std::jthread t([&ready, &readyMutex, &readyCV] (std::stop_token st)    {        while (...)        {            ...            {                std::unique_lock lg{readyMutex};                readyCV.wait_until(lg, [&ready] {return ready; }, st);                // also ends wait on stop request for st            }            ...        }   });...} // jthread destructor signals stop request and therefore unblocks the CV wait and ends the started thread

See the documentation for details:

std::condition_variable documentation

std::condition_variable_any documentation and specifically look at the wait, wait_for and wait_until member functions that now honor stop requests on jthreads.

or check out the latest jthread and stop token C++20 proposal revision


std::condition_variable is more specialized, and therefore can be more efficient when you don't need the flexibility of std::condition_variable_any.

From N3290 ยง30.5[thread.condition]/1

Class condition_variable provides a condition variable that can only wait on an object of type unique_lock<mutex>, allowing maximum efficiency on some platforms. Class condition_variable_any provides a general condition variable that can wait on objects of user-supplied lock types.

Actually, in LLVM's libc++, condition_variable_any is implemented using the more specialized condition_variable (which uses pthread_cond_t) on a shared_mutex.