2016-11-13 71 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_lockstd::lock_guard呢?這可以減輕我每次使用它時手動解鎖鎖。

回答

2

不,如果它與std::condition_variable使用需要一個std::unique_lockstd::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

我用你的第一個代碼片斷,添加包含'main',並修改lambda以返回'true'。我使用的是macOS提供的最新的clang。這裏是錯誤信息:http://codepad.org/8Xvh8O1m你的代碼是否爲你編譯?用什麼編譯器? –

相關問題