2012-10-22 27 views
8

Tôi đang cố gắng hiểu điều gì xảy ra với một mutex khi nó được sử dụng trong biến điều kiện.hiện một mutex được mở khóa khi gọi thông báo trên biến điều kiện

Trong ví dụ sau, lấy từ cppreference

int main() 
{ 
    std::queue<int> produced_nums; 
    std::mutex m; 
    std::condition_variable cond_var; 
    bool done = false; 
    bool notified = false; 

    std::thread producer([&]() { 
     for (int i = 0; i < 5; ++i) { 
      std::this_thread::sleep_for(std::chrono::seconds(1)); 
      std::unique_lock<std::mutex> lock(m); 
      std::cout << "producing " << i << '\n'; 
      produced_nums.push(i); 
      notified = true; 
      cond_var.notify_one(); 
     } 

     done = true; 
     cond_var.notify_one(); 
    }); 

    std::thread consumer([&]() { 
     std::unique_lock<std::mutex> lock(m); 
     while (!done) { 
      while (!notified) { // loop to avoid spurious wakeups 
       cond_var.wait(lock); 
      } 
      while (!produced_nums.empty()) { 
       std::cout << "consuming " << produced_nums.front() << '\n'; 
       produced_nums.pop(); 
      } 
      notified = false; 
     } 
    }); 

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

Nhà sản xuất chủ đề kêu gọi cond_var.notify_one() trước khi mutex được mở khóa. Liệu mutex m có được mở khóa khi thông báo được gọi hay không, hoặc thông báo chỉ xảy ra khi mutex được mở khóa?

Trả lời

6

Thông báo không mở khóa mutex. Bạn có thể nói (gián tiếp) bởi vì bạn không vượt qua khóa để notify_one() cách bạn làm với wait(), tính năng này sẽ giải phóng mutex trong khi chờ.

Ở phía bên kia, (các) luồng được thông báo được thông báo "ngay lập tức". Nhưng họ sẽ không nhất thiết phải quay trở lại từ wait() ngay lập tức. Trước khi họ có thể quay trở lại từ wait(), trước tiên họ phải mua lại mutex, vì vậy họ sẽ chặn ở đó cho đến khi luồng thông báo giải phóng nó.

3

Khóa đang được mua lại trong hàm khởi tạo và được giải phóng trong destructor của std::unique_lock. Từ thông tin này, bạn có thể suy ra rằng nhà sản xuất nhả khóa sau khi cuộc gọi đến số notify_one() hoàn tất.

+0

chính xác những gì đang tìm kiếm: D –

0

Vì lý do hiệu suất, tôi khuyên bạn nên mở khóa mutex trước để thông báo cho các chủ đề khác.

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