2013-03-02 29 views
36

Tôi sẽ sử dụng boost::mutex từ boost/thread/mutex.hpp. Có một số cách để khóa/mở khóa mutex: với scoped_lock, unique_lock, lock_guard, các chức năng thành viên của mutex ::lock()::unlock() và các chức năng không phải là thành viên lock()unlock().boost scoped_lock vs plain lock/mở khóa

Tôi nhận thấy rằng boost::scoped_mutex là một trong những cách phổ biến nhất để sử dụng mutex. Tại sao lại thích hợp hơn với các chức năng thành viên ::lock()::unlock()?

Đặc biệt, tại sao tôi nên sử dụng

{ 
    boost::scoped_lock lock(mutex) 
    // ... 
    // read/output sharing memory. 
    // ... 
} 

hơn

mutex.lock() 
// ... 
// read/output sharing memory. 
// ... 
mutex.unlock() 

scoped_lock tốt hơn chỉ vì một số điểm phong cách mã hóa của xem hoặc là ::lock()/::unlock() không phải là "chủ đề đủ an toàn"?

Trả lời

62

Tại sao nó thích hợp hơn với các chức năng của thành viên :: lock() và :: unlock()?

Đối với cùng một lý do tại sao RAII idiom trở nên phổ biến nói chung (điều này chỉ là một trong những trường hợp vô số của nó): bởi vì bạn có thể chắc chắn bạn không' rời khỏi phạm vi hiện tại mà không mở khóa mutex.

Thông báo, rằng đây không chỉ là về quên gọi unlock(): một ngoại lệ có thể xảy ra trong khi mutex của bạn bị khóa, và cuộc gọi của bạn để unlock() có thể không bao giờ đạt được, ngay cả khi bạn không có bất kỳ tuyên bố return giữa của bạn hãy gọi tới số lock() và gọi tới số unlock().

m.lock() // m is a mutex 
// ... 
foo(); // If this throws, your mutex won't get unlocked 
// ... 
m.unlock() 

Trong trường hợp này, destructor của scoped_lock bảo vệ của bạn sẽ được gọi trong đống thư giãn, đảm bảo các mutex liên luôn được phát hành.

{ 
    boost::scoped_lock lock(m); // m is a mutex 
    // ... 
    foo(); // If this throws, your RAII wrapper will unlock the mutex 
    // ... 
} 

Hơn nữa, trong nhiều tình huống này sẽ cải thiện khả năng đọc của mã của bạn, trong đó bạn sẽ không cần phải thêm một cuộc gọi đến unlock() trước mỗi tuyên bố return.

+0

cảm ơn bạn đã giải thích rõ ràng. – Max

+0

@Max: Vui vì nó đã giúp –

2

bạn có thể sử dụng

std::lock_guard<std::mutex> lock(mutex);

nếu không muốn sử dụng thư viện boost.