lundi 2 décembre 2019

How to wait for completion of all tasks in this ThreadPool?

I am trying to write a ThreadPool class

class ThreadPool {
  public:
    ThreadPool(size_t numberOfThreads):isAlive(true) {
      for(int i =0; i < numberOfThreads; i++) {
        workerThreads.push_back(std::thread(&ThreadPool::doJob, this));
      }

      #ifdef DEBUG 
      std::cout<<"Construction Complete"<<std::endl; 
      #endif
    }

    ~ThreadPool() {
      #ifdef DEBUG 
      std::cout<<"Destruction Start"<<std::endl; 
      #endif

      isAlive = false;
      conditionVariable.notify_all();
      waitForExecution();

      #ifdef DEBUG 
      std::cout<<"Destruction Complete"<<std::endl; 
      #endif
    }

    void waitForExecution() {
      for(std::thread& worker: workerThreads) {
        worker.join();
      }
    }

    void addWork(std::function<void()> job) {
      #ifdef DEBUG 
      std::cout<<"Adding work"<<std::endl; 
      #endif
      std::unique_lock<std::mutex> lock(lockListMutex);
      jobQueue.push_back(job);
      conditionVariable.notify_one();
    }

  private:
    // performs actual work
    void doJob() {
      // try {
        while(isAlive) {
          #ifdef DEBUG 
          std::cout<<"Do Job"<<std::endl; 
          #endif

          std::unique_lock<std::mutex> lock(lockListMutex);
          if(!jobQueue.empty()) {
            #ifdef DEBUG 
            std::cout<<"Next Job Found"<<std::endl; 
            #endif

            std::function<void()> job = jobQueue.front();
            jobQueue.pop_front();
            job();
          }
          conditionVariable.wait(lock);
        }
    }

    // a vector containing worker threads
    std::vector<std::thread> workerThreads;

    // a queue for jobs
    std::list<std::function<void()>> jobQueue;

    // a mutex for synchronized insertion and deletion from list
    std::mutex lockListMutex;

    std::atomic<bool> isAlive;

    // condition variable to track whether or not there is a job in queue
    std::condition_variable conditionVariable;
};

I am adding work to this thread pool from my main thread. My problem is calling waitForExecution() results in forever waiting main thread. I need to be able to terminate threads when all work is done and continue main thread execution from there. How should I proceed here?

Aucun commentaire:

Enregistrer un commentaire