title: Multithreading manager
body: <p>I'm trying to write a class able to manage threads in order to parallelize processes in a loop.</p>
  <p>It's the first time I use multithreading in C++, could you tell me if I'm misunderstanding something ?</p>
  <p>(to make the code shorter, I've written the definitions directly inside the class, it will be changed later)</p>
  <pre class="lang-cpp prettyprint-override"><code>using namespace std;
  
  struct ManagedThread
  {
      unique_ptr&lt;thread&gt; m_thread;
      bool m_terminated;
  
      ManagedThread(unique_ptr&lt;thread&gt; thread, bool terminated = false)
          : m_thread(move(thread)), m_terminated(terminated)
      {}
  };
  
  class ThreadsManager
  {
      mutex m_threadsMutex;
      vector&lt;unique_ptr&lt;ManagedThread&gt;&gt; m_threads;
  
      mutex m_answerMutex;
      string m_answer;
  public:
  
      void setAnswer(const string&amp; answer)
      {
          lock_guard&lt;mutex&gt; lockGuard(m_answerMutex);
          m_answer = answer;
      }
  
      string getAnswer() const
      {
          // i don't know if the mutex is needed here
          return m_answer;
      }
  
      bool isStopFlagSet()
      {
          return (&quot;&quot; != m_answer);
      }
  
      void markAsTerminated(const thread::id&amp; id)
      {
          lock_guard&lt;mutex&gt; lockGuard(m_threadsMutex);
          vector&lt;unique_ptr&lt;ManagedThread&gt;&gt;::iterator it(m_threads.begin());
          while(it != m_threads.end() &amp;&amp; (*it)-&gt;m_thread-&gt;get_id() != id)
              ++it;
  
          if(it == m_threads.end())
              return;
  
          (*it)-&gt;m_terminated = true;
      }
  
      void waitForAvailableThread()
      {
          cout &lt;&lt; &quot;waiting...................................&quot; &lt;&lt; endl;
          while(!aThreadIsTerminated())
              this_thread::yield();
  
          lock_guard&lt;mutex&gt; lockGuardThreads(m_threadsMutex);
  
          vector&lt;unique_ptr&lt;ManagedThread&gt;&gt;::iterator it(m_threads.begin());
          while(it != m_threads.end() &amp;&amp; !((*it)-&gt;m_terminated))
              ++it;
          (*it)-&gt;m_thread-&gt;join();
  
          m_threads.erase(it);
      }
  
      bool aThreadIsAvailable()
      {
          return (thread::hardware_concurrency() - m_threads.size() &gt; 0);
      }
  
      bool addThread(unique_ptr&lt;thread&gt; t)
      {
          cout &lt;&lt; &quot;nb currently running : &quot; &lt;&lt; m_threads.size() &lt;&lt; endl;
          cout &lt;&lt; &quot; ----- &quot; &lt;&lt; endl;
          lock_guard&lt;mutex&gt; lockGuardThreads(m_threadsMutex);
  
          vector&lt;unique_ptr&lt;ManagedThread&gt;&gt;::iterator it(m_threads.begin());
          while(it != m_threads.end() &amp;&amp; (*it)-&gt;m_thread != t)
              ++it;
  
          if(it == m_threads.end() &amp;&amp; m_threads.size() &lt; thread::hardware_concurrency())
          {
              m_threads.push_back(make_unique&lt;ManagedThread&gt;(move(t)));
              return true;
          }
  
          return false;
      }
  
      void waitForEndOfAllThreads()
      {
          for(const unique_ptr&lt;ManagedThread&gt;&amp; mt : m_threads)
              mt-&gt;m_thread-&gt;join();
      }
  
  private:
      bool aThreadIsTerminated()
      {
          for(vector&lt;unique_ptr&lt;ManagedThread&gt;&gt;::iterator it(m_threads.begin()); it != m_threads.end(); ++it)
              if((*it)-&gt;m_terminated)
                  return true;
          return false;
      }
  };
  
  
  void foo(int i, ThreadsManager&amp; threadManager)
  {
      for(unsigned j(0); j &lt; 10*i &amp;&amp; !threadManager.isStopFlagSet(); ++j)
      {
          this_thread::sleep_for(chrono::milliseconds(100));
          if(5 == i)
          {
              cout &lt;&lt; &quot;5 finds the answer&quot; &lt;&lt; endl;
              threadManager.setAnswer(&quot;theAnswer&quot;);
          }
      }
      cout &lt;&lt; &quot;fin : &quot; &lt;&lt; i &lt;&lt; endl;
      // lets say the 5th thread finds the answer
      threadManager.markAsTerminated(this_thread::get_id());
  }
  
  int main()
  {
      ThreadsManager allThreads;
  
      auto t1 = std::chrono::high_resolution_clock::now();
      cout &lt;&lt; thread::hardware_concurrency() &lt;&lt; endl;
  
      for(unsigned i(0); i &lt; 10 &amp;&amp; !allThreads.isStopFlagSet(); ++i)
      {
          if(!allThreads.aThreadIsAvailable())
              allThreads.waitForAvailableThread();
  
          cout &lt;&lt; &quot;start &quot; &lt;&lt; i &lt;&lt; endl;
          allThreads.addThread(make_unique&lt;thread&gt;(foo, i, ref(allThreads)));
      }
      allThreads.waitForEndOfAllThreads(); // all the threads will end
  
      cout &lt;&lt; &quot;the answer is : &quot; &lt;&lt; allThreads.getAnswer() &lt;&lt; endl;
  
      auto t2 = std::chrono::high_resolution_clock::now();
      auto duration = std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;( t2 - t1 ).count();
      std::cout &lt;&lt; duration &lt;&lt; endl;
      return 0;
  }
  </code></pre>