2012-10-22 7 views
8

mutexが条件変数で使用されたときに何が起こるのかを理解しようとしています。次の例で条件変数でnotifyを呼び出すと、mutexがロック解除されるのですか?

、ミューテックスのロックが解除される前に、プロデューサスレッドはcond_var.notify_one()を呼び出し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(); 
} 

から採取しました。 notifyが呼び出されたときにmutex mがロック解除されるか、またはmutexがロック解除されたときにのみ通知が行われますか?

答えて

6

通知すると、mutexのロックが解除されません。 へのロックをwait()へ渡すことはないので、(間接的に)伝えることができます。これは、待機中にミューテックスを解放します。

通知されたスレッドは、「すぐに」通知されます。しかし、彼らは必ずwait()からすぐに戻ることはありません。彼らはwait()から戻ることができる前に、最初にミューテックスを再度取得しなければならないので、通知スレッドがそれを解放するまでそこでブロックするでしょう。

3

ロックはコンストラクタで取得され、デストラクタで解放されます(std::unique_lock)。この情報から、notify_one()への呼び出しが完了した後、プロデューサがロックを解除することが推測できます。

+0

まさに何が探していたのですか:D –

0

パフォーマンス上の理由から、他のスレッドに通知する前にミューテックスのロックを解除することをお勧めします。

関連する問題