问题描述
我正在用 C++ 创建一个线程池系统,但在销毁我的所有线程时出现了一个奇怪的异常。这是正在发生的事情:
terminate called without an active exception
这是我的 Worker 类的代码:
Queue<Job> Worker::job_queue = Queue<Job>();
std::atomic<bool> Worker::run(false);
std::vector<Worker*> Worker::workers = std::vector<Worker*>();
std::mutex Worker::queue_mutex;
Worker::Worker() : worker_thread(Worker::loop,this){
worker_thread.detach();
workers.push_back(this);
}
void Worker::loop(){
while(Worker::run){
try{
queue_mutex.lock();
Job todo = job_queue.pop();
queue_mutex.unlock();
todo.job(todo.params);
todo.isDone = true;
} catch(...){
queue_mutex.unlock();
}
}
}
void Worker::init(){ //Static method; called when the program starts
run = true;
for(int i=0;i<NUM_OF_WORKERS;i++){
workers.push_back(new Worker());
}
}
void Worker::uninit(){ //Static method; called when the program is about to terminate
run = false;
for(int i=0;i<workers.size();i++){
delete workers[i];
}
}
为什么会发生这种情况,我该如何解决?
解决方法
-
您将同一个对象插入
workers
两次 - 首先是在Worker()
构造函数中,然后是在operator new
返回时。所以最后,你得到了双重自由——你应该使用带有智能指针的 RAII。 -
您正在手动锁定和解锁互斥锁,并拦截并吞下所有异常 - 您应该使用带有
::std::lock
对象的 RAII。 -
分离线程通常不是一个好主意,请参阅When should I use std::thread::detach?。销毁那些线程仍在使用的对象会导致麻烦。