2012-10-22 10 views
8

Sto cercando di capire cosa succede a un mutex quando viene usato in una variabile di condizione.un mutex viene sbloccato quando si chiama notify su una variabile di condizione

Nel seguente esempio, tratto da 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(); 
} 

Il produttore thread chiama cond_var.notify_one() prima che il mutex viene sbloccato. Il mutex m viene sbloccato quando viene chiamato notify o la notifica si verifica solo quando il mutex viene sbloccato?

risposta

6

La notifica non sblocca il mutex. È possibile dire (indirettamente) perché non si passa il blocco a notify_one() come si fa a wait(), che rilascia il mutex mentre è in attesa.

Sul lato opposto, la/e filettatura notificata è notificata "immediatamente". Ma non torneranno necessariamente dal wait() immediatamente. Prima di poter tornare da wait(), devono prima acquisire nuovamente il mutex, in modo da bloccarlo finché il thread di notifica non lo rilascia.

3

Il blocco viene acquisito nel costruttore e rilasciato nel distruttore di std::unique_lock. Da queste informazioni è possibile dedurre che il produttore rilascia il blocco dopo aver completato la chiamata a notify_one().

+0

esattamente quello che cercava: D –

0

Per motivi di prestazioni, suggerisco di sbloccare il mutex prima di notificare altri thread.

Problemi correlati