2012-02-21 43 views
18

Tôi rất bối rối về sự khác biệt giữa khóa và mutex. Trong tài liệu Boost, nó nói,Sự khác nhau giữa "mutex" và "lock" là gì?

Khóa các loại

  • Lớp mẫu lock_guard
  • Lớp mẫu unique_lock
  • Lớp mẫu shared_lock
  • Lớp mẫu upgrade_lock
  • Lớp mẫu upgrade_to_unique_lock
  • Mutex-class class scoped_tr y_lock

loại Mutex

  • Lớp mutex
  • typedef try_mutex
  • Lớp timed_mutex
  • Lớp recursive_mutex
  • typedef recursive_try_mutex
  • Lớp recursive_timed_mutex
  • Lớp shared_mutex

Trong một bài viết, tôi thấy các chức năng như thế này,

boost::shared_mutex _access; 
void reader() 
{ 
    boost::shared_lock<boost::shared_mutex> lock(_access); 
    // do work here, without anyone having exclusive access 
}  
void conditional_writer() 
{ 
    boost::upgrade_lock<boost::shared_mutex> lock(_access); 
    // do work here, without anyone having exclusive access 

    if (something) { 
    boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock); 
    // do work here, but now you have exclusive access 
    } 
    // do more work here, without anyone having exclusive access 
} 

Cập nhật câu hỏi

  1. bất cứ ai có thể cung cấp một số làm rõ giữa "mutex" và " Khóa"?
  2. Bạn có cần tạo một shared_lock cho số shared_mutex? Điều gì sẽ xảy ra nếu tôi tạo một unique_lock cho một số shared_mutex?
  3. Hoặc nếu tôi tạo ra một shared_lock cho một mutex, có nghĩa là các mutex thể không được chia sẻ giữa nhiều chủ đề?
+0

Bạn có thể tìm thấy bài viết của tôi "Cách hoạt động của mutex?" cũng hữu ích: http://mortoray.wordpress.com/2011/12/16/how-does-a-mutex-work-what-does-it-cost/ –

+1

Đó là những câu hỏi mới. Bạn nên hỏi họ trong một câu hỏi mới. Bạn không thêm theo dõi cho câu hỏi đã tồn tại. Ngoài ra, công cụ này là tất cả có trong tài liệu của Boost. –

Trả lời

30

A mutex là đối tượng đồng bộ hóa. Bạn có được một khóa trên một mutex ở đầu của một phần của mã, và phát hành nó ở cuối, để đảm bảo rằng không có thread khác đang truy cập cùng một dữ liệu cùng một lúc. Một mutex thường có tuổi thọ bằng với dữ liệu mà nó đang bảo vệ và một mutex được truy cập bởi nhiều luồng.

Một đối tượng khóa là một đối tượng đóng gói khóa đó.Khi đối tượng được xây dựng, nó sẽ lấy khóa trên mutex. Khi nó bị phá hủy, khóa được giải phóng. Bạn thường tạo một đối tượng khóa mới cho mọi quyền truy cập vào dữ liệu được chia sẻ.

+2

+1: Tuổi thọ của khóa là khoảng thời gian truy cập độc quyền vào một phần mã; tuổi thọ của mutex thường dành cho sự tồn tại của phần mã có thể bị khóa. –

9

Mutex là đối tượng có thể bị khóa. Khóa là đối tượng mà duy trì khóa. Để tạo khóa, bạn cần phải chuyển nó thành một mutex.

1

Locks có thể cung cấp loại trừ lẫn nhau nhưng không đặt điều kiện synchronization.Unlike một semaphore, một khóa có chủ sở hữu, và quyền sở hữu đóng một vai trò quan trọng trong hành vi của một khóa

dụ -

class lockableObject { public void F() { 
mutex.lock(); ...; mutex.unlock(); 
} 
public void G() { 
mutex.lock(); ...; F(); ...; mutex.unlock(); 
} 
private mutexLock mutex; } 
// method G() calls method F() 

Khóa mutex trong lớp lockableObject được sử dụng để biến các phương thức F() và G() thành các phần quan trọng. Do đó, chỉ có một luồng tại một thời điểm có thể thực hiện bên trong một phương thức của một lockableObject. Khi một thread gọi phương thức G(), thì mutex bị khóa. Khi phương thức G() gọi phương thức F(), mutex.lock() được thực hiện trong F(), nhưng chuỗi gọi không bị chặn vì nó đã sở hữu mutex. Nếu mutex là một semaphore nhị phân thay vì một khóa, cuộc gọi từ G() đến F() sẽ chặn thread gọi khi mutex.P() được thực hiện trong F(). (Nhớ lại rằng các phép toán của các phép toán P() và V() trên một semaphore nhị phân phải thay thế.) Điều này sẽ tạo ra bế tắc vì không có luồng nào khác có thể thực thi bên trong F() hoặc G().

Đây là sự khác biệt giữa khóa và dấu chấm phẩy nhị phân: 1 Đối với một semaphore nhị phân, nếu hai cuộc gọi được thực hiện tớiP() mà không có bất kỳ cuộc gọi can thiệp nào đến V(), lệnh gọi thứ hai sẽ chặn. Nhưng một chủ sở hữu một khóa và yêu cầu quyền sở hữu một lần nữa không bị chặn. (Hãy coi chừng thực tế là ổ khóa không phải luôn luôn đệ quy, vì vậy hãy kiểm tra tài liệu trước khi sử dụng khóa.) 2 Chủ sở hữu cho các cuộc gọi liên tiếp để khóa() và mở khóa() phải là cùng một chuỗi. Nhưng các cuộc gọi liên tiếp tới P() và V() có thể được thực hiện bởi các luồng khác nhau.

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