terminate called after throwing an instance of 'std::system_error' threadpool

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

When I run my code :

nb workers = 12 I'm i : 0 HELLO I'm func1 BYE I'm func2 terminate called after throwing an instance of 'std::system_error'   what():  Invalid argument Aborted (core dumped) 

terminate called after throwing an instance of 'std::system_error'l

what(): Invalid argument

#ifndef CPP_PLAZZA_EXAMPLE_H #define CPP_PLAZZA_EXAMPLE_H  #include <thread> #include <vector> #include <list> #include <memory> #include <functional> #include <mutex> #include <condition_variable> #include <atomic> #include <iterator> #include <tuple>  class ThreadPool {  public:   ThreadPool(size_t numThreads);   virtual ~ThreadPool();   void executeJob(std::function<void()> job, std::function<void()> notificationJob);   void wait_for_done();  private:   void loop();   std::pair<std::function<void()>, std::function<void()> > getNextJob();   std::vector<std::thread> m_workers;   std::list<std::pair<std::function<void()>, std::function<void()> > > m_jobs;   std::mutex m_lockJobsList;   std::condition_variable m_notifyJob;   std::atomic<bool> m_bTerminate;   class Terminated: public std::runtime_error   {    public:     Terminated(const std::string& what): std::runtime_error(what) {}   };  };  #endif //CPP_PLAZZA_EXAMPLE_H 

and here it is my .cpp

#include <iostream> #include "example.h"   ThreadPool::ThreadPool(size_t numThreads):  m_workers(numThreads), m_bTerminate(false) {   m_workers.reserve(numThreads);   for (size_t i = 0; i < numThreads; i++) {     this->m_workers.emplace_back(&ThreadPool::loop, this);   }   /*for (std::vector<std::thread>::iterator it = this->m_workers.begin(); it != this->m_workers.end(); it++)     assert(std::next(it, 1) ==);*/ }  ThreadPool::~ThreadPool() {     {         std::unique_lock<std::mutex> lockList(m_lockJobsList);         m_bTerminate = true;         m_notifyJob.notify_all();     }  /*  for(std::vector<std::thread>::iterator it = m_workers.begin(); it != m_workers.end(); it++) {     it->join();   }*/   std::this_thread::sleep_for(std::chrono::seconds(5)); }  void ThreadPool::executeJob(std::function<void()> job, std::function<void()> notificationJob) {     std::unique_lock<std::mutex> lockList(m_lockJobsList);   m_jobs.emplace_back(std::pair<std::function<void()>, std::function<void()> >(std::move(job), std::move(notificationJob)));   std::cout << m_jobs.size() << std::endl;     m_notifyJob.notify_one(); }  std::pair<std::function<void()>, std::function<void()> > ThreadPool::getNextJob() {     std::unique_lock<std::mutex> lockList(m_lockJobsList);      while(!m_bTerminate)     {         if(!m_jobs.empty())         {             std::pair<std::function<void()>, std::function<void()>> job = std::ref(m_jobs.front());             m_jobs.pop_front();             return job;         }          m_notifyJob.wait(lockList);     }      throw Terminated("Thread terminated"); }  void        func1() {   std::cout << "HELLO I'm func1" << std::endl;  }  void ThreadPool::loop() {     try     {         for(;;)         {       std::pair<std::function<void()>, std::function<void()> > job = getNextJob();       job.first();       job.second();         }     }     catch(Terminated& e)     {     } }    void        func2() {   std::cout << "BYE I'm func2" << std::endl;  }  void        ThreadPool::wait_for_done() {   std::cout << "nb workers = " << this->m_workers.size() << std::endl;   int i = 0;   for(std::vector<std::thread>::iterator it = m_workers.begin(); it != m_workers.end(); ++it) {     std::cout << "je suis i :  " << i << std::endl;     i++;      (*it).join();   } }  int     main() {   ThreadPool        pool(6);    pool.executeJob(func1, func2);   pool.wait_for_done(); } 

I think that my error is I join several time on one thread but how to fix it ?

Compilation line :

g++ -Wall -Werror -W -Wextra example.cpp -pthread -std=c++11 

I tried joinable before join like this (in wait for done) :

for(std::vector<std::thread>::iterator it = m_workers.begin(); it != m_workers.end(); ++it) {     if ((*it).joinable())         (*it).join();   } 

And I had an infinite loop

回答1:

Your m_lockJobsList mutex (and m_notifyJob condvar) gets destroyed before m_workers threads that try to lock it when wake after condvar notification at ThreadPool destructor.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!