C++ 线程池中的deque迭代器不可取消引用错误
我使用SDL2的线程库编写了一个线程池,它使用以下线程函数:C++ 线程池中的deque迭代器不可取消引用错误,c++,multithreading,sdl,C++,Multithreading,Sdl,我使用SDL2的线程库编写了一个线程池,它使用以下线程函数: int threadFunc(void * pData) { ThreadData* data = (ThreadData*)pData; SDLTaskManager* pool = data->pool; Task* task = nullptr; while (true) { SDL_LockMutex(pool->getMutex()); wh
int threadFunc(void * pData)
{
ThreadData* data = (ThreadData*)pData;
SDLTaskManager* pool = data->pool;
Task* task = nullptr;
while (true)
{
SDL_LockMutex(pool->getMutex());
while (!pool->isRunning() && !pool->hasTasks())
{
SDL_CondWait(pool->getCondition(), pool->getMutex());
}
if (pool->shuttingDown())
{
return 0;
}
task = pool->getNextTask(); //SDL_CondWait relocks mutex, so this *should* be thread safe.
if (task != nullptr)
{
pool->notifyThreadWorking(true);
data->taskCount++;
}
else
{
pool->stop();
SDL_UnlockMutex(pool->getMutex());
continue;
}
SDL_UnlockMutex(pool->getMutex());
task->execute();
SDL_LockMutex(pool->getMutex());
pool->notifyThreadWorking(false);
pool->addCompleteTask(task);
SDL_UnlockMutex(pool->getMutex());
}
return 0;
}
当调用pool->getnextask()时,我得到调试断言错误“Deque迭代器不可解引用”。我检查了池通过调用堆栈维护的deque的内容,发现调用此函数时它肯定不是空的
功能代码如下:
Task * SDLTaskManager::getNextTask()
{
Task* t = nullptr;
if (!mCurrentTasks.empty())
{
t = mCurrentTasks.front(); //this part is causing the error
mCurrentTasks.pop_front(); //this is a std::deque<Task*>
}
return t;
}
Task*SDLTaskManager::getNextTask()
{
Task*t=nullptr;
如果(!mCurrentTasks.empty())
{
t=mcurrentstasks.front();//此部分导致错误
mcurrentstasks.pop_front();//这是一个std::deque
}
返回t;
}
deque中包含有效数据,因此我不知道是什么导致了问题。有一件事我觉得可能是错的:您必须先锁定互斥锁,然后等待条件变量,它将自动释放锁。此外,检查是否有任务,然后不加锁地处理它们也不起作用。在其他线程可能已经处理了该任务之后,检索该任务可能会在某个未指定的时间之后发生。最后,没有一个最小但完整的例子,你的问题被认为是离题的。为了演示,请考虑一下Deq迭代器,但在任何地方都看不到DEGO……UlrichEckhardt,我认为条件变量要求您在执行操作之前已经持有互斥锁,如果我在多个线程中运行那个函数,在调用SDL_CondWait之前锁定互斥锁不会造成死锁情况吗?不确定,文档怎么说?你的尝试显示了什么?您对条件变量的理解是什么?根据文档,如果一个互斥锁被锁定,其他试图锁定同一互斥锁的线程将被阻止,直到使用SDL_CondWait再次解锁互斥锁,解锁互斥锁然后等待信号。收到信号后,互斥锁再次锁定,然后继续。我已更新代码以反映此信息。debug assertation失败的问题仍然存在,代码到达t=mCurrentTasks.front(),并崩溃,表明deque迭代器不可取消引用。再次检查deque的内容将确认非空deque状态。