title: Using std::condition_variable with atomic<bool>
body: <p>There are several questions on SO dealing with atomic, and other that deal with std::condition_variable. But my question if my use below is correct?</p>
  
  <p>Three threads, one ctrl thread that does preparation work before unpausing the two other threads. The ctrl thread also is able to pause the worker threads (sender/receiver) while they are in their tight send/receive loops.
  The idea with using the atomic is to make the tight loops faster in case the boolean for pausing is not set.</p>
  
  <pre><code>class SomeClass
  {
  
  public:
      //...                                                                                                                                                                                                                                                                                                                                                                                   
      // Disregard that data is public...                                                                                                                                                                                                                                                                                                                                                     
  
      std::condition_variable cv; // UDP threads will wait on this cv until allowed                                                                                                                                                                                                                                                                                                           
                                  // to run by ctrl thread.                                                                                                                                                                                                                                                                                                                                   
      std::mutex cv_m;
      std::atomic&lt;bool&gt; pause_test_threads;
  };
  
  void do_pause_test_threads(SomeClass *someclass)
  {
      if (!someclass-&gt;pause_test_threads)
      {
          // Even though we use an atomic, mutex must be held during                                                                                                                                                                                                                                                                                                                          
          // modification. See documentation of condition variable                                                                                                                                                                                                                                                                                                                            
          // notify_all/wait. Mutex does not need to be held for the actual                                                                                                                                                                                                                                                                                                                   
          // notify call.                                                                                                                                                                                                                                                                                                                                                                     
          std::lock_guard&lt;std::mutex&gt; lk(someclass-&gt;cv_m);
          someclass-&gt;pause_test_threads = true;
      }
  }
  
  void unpause_test_threads(SomeClass *someclass)
  {
      if (someclass-&gt;pause_test_threads)
      {
          {
              // Even though we use an atomic, mutex must be held during                                                                                                                                                                                                                                                                                                                      
              // modification. See documentation of condition variable                                                                                                                                                                                                                                                                                                                        
              // notify_all/wait. Mutex does not need to be held for the actual                                                                                                                                                                                                                                                                                                               
              // notify call.                                                                                                                                                                                                                                                                                                                                                                 
              std::lock_guard&lt;std::mutex&gt; lk(someclass-&gt;cv_m);
              someclass-&gt;pause_test_threads = false;
          }
          someclass-&gt;cv.notify_all(); // Allow send/receive threads to run.                                                                                                                                                                                                                                                                                                                   
      }
  }
  
  void wait_to_start(SomeClass *someclass)
  {
      std::unique_lock&lt;std::mutex&gt; lk(someclass-&gt;cv_m); // RAII, no need for unlock.                                                                                                                                                                                                                                                                                                          
      auto not_paused = [someclass](){return someclass-&gt;pause_test_threads == false;};
      someclass-&gt;cv.wait(lk, not_paused);
  }
  
  void ctrl_thread(SomeClass *someclass)
  {
      // Do startup work                                                                                                                                                                                                                                                                                                                                                                      
      // ...                                                                                                                                                                                                                                                                                                                                                                                  
      unpause_test_threads(someclass);
  
      for (;;)
      {
          // ... check for end-program etc, if so, break;                                                                                                                                                                                                                                                                                                                                     
          if (lost ctrl connection to other endpoint)
          {
              pause_test_threads();
          }
          else
          {
              unpause_test_threads();
          }
          sleep(SLEEP_INTERVAL);
  
      }
  
      unpause_test_threads(someclass);
  }
  
  void sender_thread(SomeClass *someclass)
  {
      wait_to_start(someclass);
      ...
      for (;;)
      {
          // ... check for end-program etc, if so, break;                                                                                                                                                                                                                                                                                                                                     
          if (someclass-&gt;pause_test_threads) wait_to_start(someclass);
          ...
      }
  }
  
  void receiver_thread(SomeClass *someclass)
  {
      wait_to_start(someclass);
      ...
      for (;;)
      {
          // ... check for end-program etc, if so, break;                                                                                                                                                                                                                                                                                                                                     
          if (someclass-&gt;pause_test_threads) wait_to_start(someclass);
          ...
      }
  </code></pre>