2013-02-05 38 views
19

Xin vui lòng, bất cứ ai có thể giải thích làm thế nào để sử dụng và tạo ra một unique_lock trong c + +? Nó nên được sử dụng cả hai để có được loại trừ lẫn nhau với bất kỳ thủ tục của màn hình và để có thể thực hiện wait() trên biến điều kiện ... Tôi không hiểu từ tài liệu hướng dẫn như thế nào tôi phải tạo ra nó. Là một mutex cần thiết? Đây là một pseudo-code:Làm thế nào để sử dụng/tạo unique_lock trong c + +?

/* 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(); 
} 

Trả lời

-2

Trong trường hợp này, tôi nghĩ rằng tất cả các bạn cần làm là:

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

-1 _not_ ngoại lệ an toàn. – ildjarn

22

std::unique_lock sử dụng mô hình RAII.

Khi bạn muốn khóa một mutex, bạn tạo một biến cục bộ loại std::unique_lock chuyển mutex làm tham số. Khi unique_lock được xây dựng, nó sẽ khóa mutex, và nó bị phá hủy nó sẽ mở khóa mutex. Quan trọng hơn: Nếu một ngoại lệ được ném ra, số std::unique_lock destructer sẽ được gọi và do đó mutex sẽ được mở khóa.

Ví dụ:

#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> giữ một khóa trên một đối tượng riêng biệt std::mutex. Bạn liên kết đối tượng khóa với mutex bằng cách truyền nó vào hàm tạo. Trừ khi bạn chỉ định khác, mutex sẽ bị khóa ngay lập tức. Nếu đối tượng khóa giữ khóa khi nó bị phá hủy thì destructor sẽ giải phóng khóa. Thông thường, đối tượng std::unique_lock<std::mutex> do đó sẽ là biến cục bộ, được khai báo tại thời điểm bạn muốn lấy khóa.

Trong trường hợp của bạn, chức năng produce() có thể được viết như thế này:

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 
} 

Lưu ý rằng tôi đã thay thế if với một while chiếm tỉnh xạ giả từ đầu wait() gọi.

+0

Bạn có 'else' không có' if'. –

7

Một mẫu mã chi tiết sử dụng các biến điều kiện:

#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

mở khóa rõ ràng là không cần thiết. tra cứu cách unique_lock() hoạt động. – Prab

+0

@Prab, chỉ để đưa ra lời giải thích: unique_lock() được tự động phát hành khi destructor được gọi là có nghĩa là nó là ngoại lệ an toàn và nó sẽ tự động mở khi bạn rời khỏi phạm vi. – EliSquared

Các vấn đề liên quan