2013-02-05 51 views
19

請問任何人都可以解釋如何在C++中使用和創建unique_lock? 它應該用於互相排斥監視器的任何過程,並且能夠對條件變量執行wait()...我不瞭解我應該如何創建它。是否需要互斥鎖?下面是一個僞代碼:如何在C++中使用/創建unique_lock?

/* compile with g++, flags -std=c++0x -lpthread */ 

#include <condition_variable> 
#include <mutex> 
#include <thread> 
#include <iostream> 
#include <string.h> 
#include <unistd.h> 

class monitorTh { 

private: 

    std::mutex m; 
    std::condition_variable waitP; 
    std::condition_variable waitC; 
    char element[32]; 
    std::unique_lock::unique_lock l; 

public: 
    void produce(char* elemProd) { 
     l.lock(); 
     if (/*already_present_element*/) { 
      waitP.wait(l); 
     } 
     else {/*produce element*/} 
     l.unlock(); 
    } 

    void consume() { 
     /*something specular*/ 
    } 
}; 

int main(int argc, char* argv[]) { 

    monitorTh* monitor = new monitorTh(); 
    char prodotto[32] = "oggetto"; 

    std::thread producer([&]() { 
     monitor->produce(prodotto); 
    }); 

    std::thread consumer([&]() { 
     monitor->consume(); 
    }); 

    producer.join(); 
    consumer.join(); 
} 

回答

-2

在這種情況下,我認爲,所有你需要做的是:

m.lock(); 
// Critical section code 
m.unlock(); 
+10

-1 _not_異常安全。 – ildjarn

22

std::unique_lock使用RAII模式。

當您想鎖定互斥鎖時,您將創建一個類型爲std::unique_lock的本地變量,並將互斥鎖作爲參數傳遞。當構造unique_lock時,它將鎖定互斥鎖,並且它被破壞,它將解鎖互斥鎖。更重要的是:如果拋出異常,將調用std::unique_lock破壞者被調用,因此互斥鎖將被解鎖。

實施例:

#include<mutex> 
int some_shared_var=0; 

int func() { 
    int a = 3; 
    { //Critical session 
     std::unique_lock<std::mutex> lock(my_mutex); 
     some_shared_var += a; 
    } //End of critical session 
}   
4

std::unique_lock<std::mutex>保持一個單獨的std::mutex對象的鎖。通過在構造函數中傳遞它來將鎖對象與互斥鎖相關聯。除非你另有指定,否則互斥鎖將立即鎖定。如果鎖對象在銷燬時保存鎖,則析構函數將釋放該鎖。通常,std::unique_lock<std::mutex>對象因此將是一個局部變量,在您希望獲取鎖的位置聲明。

在你的情況下,produce()函數可以這樣寫:

void produce(char* elemProd) { 
    std::unique_lock<std::mutex> lk(m); // lock the mutex 
    while (/*already_present_element*/) { // condition variable waits may wake spuriously 
     waitP.wait(lk); 
    } 
    {/*produce element*/} 
    // lk releases the lock when it is destroyed 
} 

請注意,我已經取代了ifwhile考慮從wait()通話虛假喚醒。

+0

你有一個沒有'if'的'else'。 –

7

A,使用條件變量的更詳細的示例代碼:

#include<mutex> 
std::mutex(mu); //Global variable or place within class 
std::condition_variable condition; //A signal that can be used to communicate between functions 

auto MyFunction()->void 
{ 
    std::unique_lock<mutex> lock(mu); 
    //Do Stuff 
    lock.unlock(); //Unlock the mutex 
    condition.notify_one(); //Notify MyOtherFunction that this is done 
} 

auto MyOtherFunction()->void 
{ 
    std::unique_lock<mutex> lock(mu); 
    condition.wait(lock) //Wait for MyFunction to finish, a lambda can be passed also to protects against spurious wake up e.g (lock,[](){return *some condition*}) 
    lock.unlock(); 
} 
+1

顯式解鎖是不必要的。查看unique_lock()的行爲。 – Prab

+0

@Prab,只是爲了給出解釋:當調用析構函數時,unique_lock()會自動釋放,這意味着它是異常安全的,並且當您離開scope時它會自動解鎖。 – EliSquared