title: Loop timer thread
body: <p>I would like to create thread pool for loop timer: for each <code>n</code> seconds, we will run task. </p>
  
  <p>In my example, we have two tasks. For each task, I will create one thread to run. I add the condition of status for each task, if the status is <code>false</code>, we do nothing. I need the status to control the timer, I can call the timer start/stop (sorry, in this code, there is only start function).</p>
  
  <p>Here is my code:</p>
  
  <pre><code> #include &lt;iostream&gt;
  #include &lt;list&gt;
  #include &lt;functional&gt;
  #include &lt;map&gt;
  #include &lt;thread&gt;
  #include &lt;chrono&gt;
  #include &lt;vector&gt;
  #include &lt;mutex&gt;
  
  //using namespace std::chrono_literals;
  
  void print_time()
  {
      std::chrono::time_point&lt;std::chrono::system_clock&gt; now = std::chrono::system_clock::now();
      std::chrono::system_clock::duration tp = now.time_since_epoch();
      tp -= std::chrono::duration_cast&lt;std::chrono::seconds&gt;(tp);
      std::time_t ttp = std::chrono::system_clock::to_time_t(now);
      tm t = *gmtime(&amp;ttp);
  
      std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u]: ", t.tm_year + 1900,
                  t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
                  static_cast&lt;unsigned&gt;(tp/std::chrono::milliseconds(1)));
  }
  
  typedef std::function&lt;void()&gt; Callback;
  
  enum E_NUM {
      NUM_ONE = 0,
      NUM_TWO
  };
  
  class Foo {
      public:
          static Foo&amp; getInstance()
          {
              static Foo instance;
              return instance;
          }
  
          void init() {
              m_mapThreadStatus[NUM_ONE] = false;
              m_mapThreadStatus[NUM_TWO] = false;
              m_mapCallback[NUM_ONE] = std::bind(&amp;Foo::test, this);
              m_mapCallback[NUM_TWO] = std::bind(&amp;Foo::foo_test, this);
          }
  
          void addTimer(E_NUM id, int num_seconds) {
              std::thread th ([id, num_seconds] () {
                      std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; " id: " &lt;&lt; id &lt;&lt; "\tseconds: " &lt;&lt; num_seconds &lt;&lt; std::endl;
                      while (1)
                      {
                          if ( Foo::getInstance().getStatus(id) == true)
                          {
                              Foo::getInstance().callfunctor(id);
                              std::this_thread::sleep_for(std::chrono::seconds(num_seconds));
                          }
                          else
                          {
                          }
                          //std::this_thread::sleep_for(std::chrono::seconds(num_seconds));
                      }
                  });
              m_mapThreads[id] = std::move(th);
          }
  
          void callfunctor(E_NUM id) {
              m_mapCallback[id]();
          }
  
          void startTimers(E_NUM id) {    
              m_mapThreadStatus[id] = true;
              if (m_mapThreads[id].joinable())
              {
                  m_mapThreads[id].join();
              }
          }
  
          bool getStatus(E_NUM id) { 
              return m_mapThreadStatus[id];}
  
      private:
          void test() {
              print_time();
              std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; std::endl;
              std::cout &lt;&lt; "\033[1;31m" &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; "\033[0m" &lt;&lt; std::endl;
          }
          void foo_test() {
              print_time();
              std::cout &lt;&lt; std::this_thread::get_id() &lt;&lt; std::endl;
              std::cout &lt;&lt; "\033[1;32m" &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; "\033[0m" &lt;&lt; std::endl;
          }
          Foo() {init();}
          std::map&lt;E_NUM, Callback&gt; m_mapCallback;
          std::vector&lt;std::thread&gt; m_threads;
          std::map&lt;E_NUM, std::thread&gt; m_mapThreads;
          std::map&lt;E_NUM, bool&gt; m_mapThreadStatus;
  };
  
  int main()
  {
      Foo::getInstance().addTimer(NUM_ONE, 1);
      Foo::getInstance().addTimer(NUM_TWO, 2);
      Foo::getInstance().startTimers(NUM_ONE);
      Foo::getInstance().startTimers(NUM_TWO);
      return 0;
  }
  </code></pre>
  
  <p>But my problem:
  1. it seems that only one task run, not two as expect.</p>
  
  <pre><code>40557398533888 id: 0    seconds: 1140557390141184 id: 1 seconds: 2
  [2019-05-28 11:56:49.770]: 140557398533888
  void Foo::test()
  
  [2019-05-28 11:56:50.770]: 140557398533888
  void Foo::test()
  [2019-05-28 11:56:51.771]: 140557398533888
  void Foo::test()
  [2019-05-28 11:56:52.771]: 140557398533888
  void Foo::test()
  [2019-05-28 11:56:53.772]: 140557398533888
  void Foo::test()
  </code></pre>
  
  <ol start="2">
  <li>The classical question: when we create the std::thread, it runs immediately, right? For example, <a href="https://stackoverflow.com/questions/25524775/delayed-start-of-a-thread-in-c-11">link</a>. So, how can I improve my code to start after adding timer?</li>
  </ol>
  
  <h1>EDIT 1:</h1>
  
  <p>I added the function in <code>Foo</code>:</p>
  
  <pre><code>class Foo {
      ...
      void startTimers() {
          m_mapThreads[NUM_ONE].join();
          m_mapThreads[NUM_TWO].join();
      }
  };
  </code></pre>
  
  <p>And I call this function at the END of main, it works like a charm. Thank you.</p>