Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

c++ - What is the difference between std::condition_variable and std::condition_variable_any?

I'm probably missing something obvious, but I can't see any difference between std::condition_variable and std::condition_variable_any. Why do we need both?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...