2012-10-22 5 views
8
freigegeben

Ich versuche zu verstehen, was mit einem Mutex passiert, wenn es in einer Bedingungsvariablen verwendet wird.wird ein Mutex beim Aufruf von notify für eine Bedingungsvariable

Im folgenden Beispiel aus genommen 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(); 
} 

Der Produzent Thread ruft cond_var.notify_one() vor der Mutex freigeschaltet wird. Wird der Mutex m beim Aufruf von notify entsperrt, oder erfolgt die Benachrichtigung nur, wenn der Mutex entsperrt wird?

Antwort

6

Durch die Benachrichtigung wird der Mutex nicht entsperrt. Sie können (indirekt) sagen, weil Sie die Sperre nicht an notify_one() übergeben, wie Sie es an wait() tun, wodurch der Mutex freigegeben wird, während er wartet.

Auf der anderen Seite werden die notifizierten Threads "sofort" gemeldet. Aber sie werden nicht sofort von wait() sofort zurückkehren. Bevor sie von wait() zurückkehren können, müssen sie zuerst den Mutex neu akquirieren, damit sie dort blockieren, bis der Benachrichtigungs-Thread sie freigibt.

3

Die Sperre wird im Konstruktor erfasst und im Destruktor std::unique_lock freigegeben. Aus dieser Information können Sie ableiten, dass der Produzent die Sperre nach dem Aufruf von notify_one() beendet.

+0

genau wonach gesucht wurde: D –

0

Aus Leistungsgründen schlage ich vor, den Mutex vorher zu entsperren, um andere Threads zu benachrichtigen.

Verwandte Themen