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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…