2016-11-13 10 views
2

Я использую std::condition_variable в сочетании с std::unique_lock вот так.Можно использовать std :: condition_variable с std :: lock_guard?

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(); 

Он отлично работает. Как я понимаю, std::condition_variable принимает std::unique_lock для его ожидания. Но, я пытаюсь совместить его с std::lock_guard, но не смог.

Мой вопрос:Можно ли заменить std::unique_lock с std::lock_guard вместо этого? Это может освободить меня от ручного разблокирования замка каждый раз, когда я его использую.

ответ

2

Нет, a std::unique_lock необходим, если он используется с std::condition_variable. std::lock_guard может иметь меньше накладных расходов, но не может использоваться с std::condition_variable.

Но std::unique_lock не нужно разблокировать вручную, он также разблокируется, когда он выходит из сферы действия, например std::lock_guard. Таким образом, код ожидания можно записать в виде:

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 
} 

См http://en.cppreference.com/w/cpp/thread/unique_lock

2

Невозможно, но вам это действительно не нужно.

std::unique_lock автоматически unlocks itself in destructor, если было заблокировано.

+0

спасибо за такую ​​быстрое осветление. Оба ответа приемлемы кстати. Просто выберите один из –

3

Любой вызов wait() на переменной условия всегда нужно lock() и unlock() лежащий в основе mutex. Поскольку обертка lock_guard<> не предоставляет эти функции, она может никогда не использовать с wait().

Еще вы можете написать свою собственную обычную обертку мьютексов на основе lock_guard<> и добавить 2 необходимых метода. Кроме того, вы должны использовать condition_variable_any, который принимает любые блокировки/мьютекс с замком()/разблокировать интерфейс():

#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; 
}; 

А потом:

#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 ... 
... 
+1

. Кажется, я не могу заставить 'lock_guard' работать с' condition_variable_any'. В сообщении об ошибке говорится о недостающих функциях-членах 'lock()' и 'unlock()'. Почему это? –

+0

Не могли бы вы добавить дополнительные сведения (компилятор, сообщение об ошибке, код)? Возможно, было бы еще проще создать новый вопрос. –

+1

Я использовал ваш первый код, отрезанный, добавляет include, 'main' и модифицировал лямбда, чтобы просто вернуть' true'. Я использую последний clang, предоставленный macOS. Вот сообщения об ошибках: http://codepad.org/8Xvh8O1m Содержит ли ваш код для вас? С каким компилятором? –

 Смежные вопросы

  • Нет связанных вопросов^_^