title: Condition Variable with a while loop in thread in C++
body: <p>I'm trying to figure out how to use <code>std::condition_variable</code> in C++ implementing a "strange" producer and consumer program in which I had set a limit to the <code>count</code> variable.</p>
  
  <p>The main thread ("producer") increments the count and must wait for this to return to zero to issue a new increment.</p>
  
  <p>The other threads enters in a loop where they have to decrease the counter and issue the notification.</p>
  
  <p>I am blocked because it is not clear to me how to conclude the program by orderly exiting the while loop inside the function of all threads.</p>
  
  <p>Could someone give me some guidance on how to implement it, please?</p>
  
  <h2>Code</h2>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  
  #include &lt;thread&gt;
  #include &lt;condition_variable&gt;
  #include &lt;vector&gt;
  
  int main() {
          int n_core = std::thread::hardware_concurrency();
      std::vector&lt;std::thread&gt; workers;
      int max = 100;
      int count = 0;
      std::condition_variable cv;
      std::mutex mutex;
      int timecalled = 0;
  
  
      for (int i = 0; i &lt; n_core; i++) {
          workers.emplace_back(std::thread{[&amp;max, &amp;count, &amp;mutex, &amp;cv]() {
              while (true) {
                  std::unique_lock&lt;std::mutex&gt; lk{mutex};
                  std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " cv" &lt;&lt; std::endl;
                  cv.wait(lk, [&amp;count]() { return count == 1; });
                  std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " - " &lt;&lt; count &lt;&lt; std::endl;
                  count--;
                  std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " notify dec" &lt;&lt; std::endl;
                  cv.notify_all();
              }
          }});
      }
  
      while (max &gt; 0) {
          std::unique_lock&lt;std::mutex&gt; lk{mutex};
          std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " cv" &lt;&lt; std::endl;
          cv.wait(lk, [&amp;count]() { return count == 0; });
          std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " created token" &lt;&lt; std::endl;
          count++;
          max--;
          timecalled++;
          std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " notify inc" &lt;&lt; std::endl;
  
          cv.notify_all();
      }
  
      for (auto &amp;w : workers) {
          w.join();
      }
  
      std::cout &lt;&lt; timecalled &lt;&lt; std::endl; // must be equal to max
      std::cout &lt;&lt; count &lt;&lt; std::endl; // must be zero
  
  }
  </code></pre>
  
  <h2>Problem</h2>
  
  <p>The program doesn't end because it is stuck on some final <code>join</code>.</p>
  
  <h2>Expected Result</h2>
  
  <p>The expected result must be:</p>
  
  <pre><code>100
  0
  </code></pre>
  
  <h2>Edits Made</h2>
  
  <p><strong>EDIT 1</strong> : I replaced <code>max &gt; 0</code> in the while with a <code>true</code>. Now the loops are unbounded, but using the solution of @prog-fh seems to work.</p>
  
  <p><strong>EDIT 2</strong> : I added a variable to check the result in the end.</p>
  
  <p><strong>EDIT 3</strong>: I changed <code>while(true)</code> to <code>while(max &gt;0)</code>. Could this be a problem in concurrency because we are reading it without a lock?</p>