简体   繁体   English

是否可以将std :: condition_variable与std :: lock_guard一起使用?

[英]Is possible to use std::condition_variable with std::lock_guard?

I am using a std::condition_variable combined with a std::unique_lock like this. 我正在使用std::condition_variablestd::unique_lock这样的结合。

std::mutex a_mutex;
std::condition_variable a_condition_variable;
std::unique_lock<std::mutex> a_lock(a_mutex);
a_condition_variable.wait(a_lock, [this] {return something;});
//Do something
a_lock.unlock();

It works fine. 它工作正常。 As I understand, std::condition_variable accepts a std::unique_lock for it to wait. 据我所知, std::condition_variable接受std::unique_lock让它等待。 But, I am trying to combine it with std::lock_guard but not able to. 但是,我试图将它与std::lock_guard结合但不能。

My question is: Is it possible to replace std::unique_lock with a std::lock_guard instead ? 我的问题是: 是否可以用std::lock_guard替换std::unique_lock This can relieve me from manually unlocking the lock every time I use it. 这可以减轻我每次使用时手动解锁锁的麻烦。

No, a std::unique_lock is needed if it is used with std::condition_variable . 不,如果与std::condition_variable一起使用,则需要std::unique_lock std::lock_guard may have less overhead, but it cannot be used with std::condition_variable . std::lock_guard可能具有较少的开销,但它不能与std::condition_variable一起使用。

But the std::unique_lock doesn't need to be manually unlocked, it also unlocks when it goes out of scope, like std::lock_guard . 但是std::unique_lock不需要手动解锁,当它超出范围时也会解锁,比如std::lock_guard So the waiting code could be written as: 所以等待代码可以写成:

std::mutex a_mutex;
std::condition_variable a_condition_variable;
{
    std::unique_lock<std::mutex> a_lock(a_mutex);
    a_condition_variable.wait(a_lock, [this] {return something;});
    //Do something
}

See http://en.cppreference.com/w/cpp/thread/unique_lock 请参见http://en.cppreference.com/w/cpp/thread/unique_lock

Any call to wait() on a condition variable will always need to lock() and unlock() the underlying mutex . 对条件变量的任何对wait()调用总是需要lock()unlock()底层mutex Since the wrapper lock_guard<> does not provide these functions, it can never be used with wait() . 由于包装器lock_guard<>不提供这些功能,因此它永远不能与wait()一起使用。

Still you could write your own simple mutex wrapper based on lock_guard<> , and add the 2 necessary methods. 你仍然可以编写自己的基于lock_guard<>的简单互斥包装器,并添加2个必要的方法。 Additionally you would have to use condition_variable_any , which accepts any lock/mutex with a lock()/unlock() interface: 此外,您必须使用condition_variable_any ,它接受带锁()/ unlock()接口的任何锁/互斥锁:

#include <mutex>

template<typename _mutex_t>
class my_lock_guard
{
public:
    explicit my_lock_guard(_mutex_t & __m) : __mutex(__m)
    { __mutex.lock(); }

    my_lock_guard(_mutex_t & __m, std::adopt_lock_t) : __mutex(__m)
    { } // calling thread owns mutex

    ~my_lock_guard()
    { __mutex.unlock(); }

    void lock()
    { __mutex.lock(); }

    void unlock()
    { __mutex.unlock(); }   

    my_lock_guard(const my_lock_guard &) = delete;
    my_lock_guard& operator=(const my_lock_guard &) = delete;

private:
    _mutex_t &  __mutex;
};

And then: 然后:

#include <condition_variable>
...
std::mutex m;
my_lock_guard<std::mutex> lg(m);
std::condition_variable_any cva;
cva.wait(lg, [] { return something;});  
// do something ...
...

Impossible, but you don't actually need that. 不可能,但你实际上并不需要那样。

std::unique_lock automatically unlocks itself in destructor , if it was locked. std::unique_lock 会在析构函数中自动解锁 ,如果它已被锁定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM