wait on thread creation

下面的範例是一般worker thread的做法,利用boost threadgroup,在程式一開始由一個thread進入(main thread),離開的時候也是一個thread
一般來說在創建thread時不需要等待thread被創建完成再往下走,不過這裡示範了當所有thread建立完成後main thread才繼續往下執行(透過condition variable, wait)
這麼做可以讓控制流變的簡潔,並且視thread group的threads為一整體,也能確保在start()完成之前不會執行stop()。

ThreadManager.h

#include 
#include 
#include 
#include 
#include 
class ThreadManager
{
  std::mutex m;
  std::condition_variable cv;
  int numThreads = 5; //non-static data member with initializer (C++11)
  int startCount = 0;
  bool bRunning = true;
  boost::thread_group threads;
  ThreadManager()
  {
  }
public:
  static ThreadManager& getInstance()
  {
    static ThreadManager m;
    return m;
  }
  void start()
  {
    for(int i = 0; i< numThreads; i++)
    {
      threads.create_thread([this]{
        int id = startCount;
        {
          std::lock_guard lk(m);
          startCount++;
          std::cout << "thread " << id << " created" << std::endl;
        }
        cv.notify_one();
        while(bRunning)
        {
          //do something
          std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
        std::cout << "thread " << id  << " finished" << std::endl;
      });
    }
    std::unique_lock lk(m);
    cv.wait(lk, [this]{return startCount == numThreads;});
    //這裡等到全部thread開始執行時才往下走
  }
  void stop()
  {
    std::cout << "stopping threads..." << std::endl;
    bRunning = false; //這邊最好要有memory fence
    threads.join_all();
    std::cout << "threads stopped" << std::endl;
  }
};

main.cpp

#include 
#include 
#include 
#include "ThreadManager.h"

int main()
{
  ThreadManager& tm = ThreadManager::getInstance();
  tm.start();
  std::cout << "threads created, wait 5 seconds and stop" << std::endl;
  std::this_thread::sleep_for(std::chrono::milliseconds(5000));
  tm.stop();
}
This entry was posted in Tips. Bookmark the permalink.

Leave a Reply