2012-10-22 70 views
8

我想了解互斥鎖在條件變量中使用時會發生什麼。當調用條件變量的通知時,互斥鎖是否會被解鎖

在以下示例中,從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(); 
} 

採取的生產者線程調用cond_var.notify_one()互斥被解鎖之前。當通知被調用時互斥鎖m是否被解鎖,或者僅當互斥鎖被解鎖時纔會發生通知?

回答

6

通知不會解鎖互斥鎖。您可以(間接地)說出,因爲您沒有將密碼鎖定爲notify_one(),您的方法是wait(),它在等待時釋放互斥鎖。

另一方面,通知線程是「立即」通知的。但他們不一定立即從wait()返回。在它們可以從wait()返回之前,它們必須首先重新獲取互斥體,以便它們在那裏阻塞,直到通知線程釋放互斥體。

3

該鎖正在構造函數中獲取,並在std::unique_lock的析構函數中釋放。從這個信息你可以推斷,在notify_one()的呼叫完成後,製作人釋放鎖定。

+0

究竟是在找什麼:D –

0

由於性能的原因,我建議解鎖互斥之前通知其他線程。

相關問題