在抛出“std::system_error”线程池的实例后调用终止
Posted
技术标签:
【中文标题】在抛出“std::system_error”线程池的实例后调用终止【英文标题】:terminate called after throwing an instance of 'std::system_error' threadpool 【发布时间】:2017-09-26 19:25:20 【问题描述】:当我运行我的代码时:
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)
在抛出 'std::system_error'l 的实例后调用终止
what(): 无效参数
#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
这是我的.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();
我认为我的错误是我在一个线程上多次加入但如何解决?
编译行:
g++ -Wall -Werror -W -Wextra example.cpp -pthread -std=c++11
我在加入之前尝试过可加入(等待完成):
for(std::vector<std::thread>::iterator it = m_workers.begin(); it != m_workers.end(); ++it)
if ((*it).joinable())
(*it).join();
我有一个无限循环
【问题讨论】:
不要join
一个线程,除非它是joinable
?
我在加入之前尝试加入,我有一个无限循环
【参考方案1】:
以防万一有人仍然需要这个 这可能会发生,因为您的线程既没有加入也没有分离。 您在主线程中使用的每个线程都必须具有以下命令之一:
-
thread_name.join()
thread_.detatch()
要知道这些命令到底在做什么,我建议简单地用谷歌搜索它。 这是我解决问题的方法,希望对您有所帮助。
【讨论】:
【参考方案2】:您的m_lockJobsList
互斥锁(和m_notifyJob
condvar)在m_workers
线程在ThreadPool
析构函数通知condvar 通知后唤醒时尝试锁定它之前被销毁。
【讨论】:
由于detach
googletest 案例下的detach
线程,我有一个高度间歇性的核心转储和头疼。原来和你在这里描述的完全一样,谢谢。我在TEST
退出之前在底部使用std::vector<std::thread> v0;
和std::for_each(v0.begin(),v0.end(),[](std::thread& t)t.join(););
解决了这个问题。这样可以确保我的本地互斥体在线程需要时能够持续更长时间。
这也帮助了我。在我发现这个问题之前,我一直很努力地挠头。谢谢!以上是关于在抛出“std::system_error”线程池的实例后调用终止的主要内容,如果未能解决你的问题,请参考以下文章
在抛出 'std::system_error' 的实例后调用终止
C++ 线程,std::system_error - 不允许操作? [复制]
xmake经验总结1:解决c++ future/promise抛出std::system_error的问题
xmake经验总结1:解决c++ future/promise抛出std::system_error的问题