我有一个简单的线程池,它需要能够等待它的工作人员在不使用标准thread::join()的情况下使用队列中的所有任务,因为我不想杀死线程本身,而只是等待它们在执行循环中完成所有任务。我想使用condition_variable来实现这一点,如下所示:
ThreadPool.cpp
void ThreadPool::addTask(ThreadTaskFunction task, void *arg) {
std::lock_guard<std::mutex> t_lock(task_lock);
tasks.push_back(ThreadTask(task, arg));
// For every tasks that is added, I increment a counter
assignedTasks++;
}
void ThreadPool::join() {
std::unique_lock<std::mutex> lock(join_lock);
joinCondition.wait(lock, [this](){
return assignedTasks == 0;
});
}Thread.cpp注意:这是ThreadPool的朋友类
void Thread::threadLoop() {
while (!shouldDie) {
ThreadTask task;
if (pool.hasTasks()) {
{
std::lock_guard<std::mutex> lock(pool.task_lock);
if (!pool.hasTasks()) continue;
task = pool.getTask();
}
task.function(task.argument);
this->completeTask();
}
}
this->isThreadFinished = true;
}
void Thread::completeTask() {
std::lock_guard<std::mutex> guard(pool.task_lock);
// When a task is completed, I decrement the counter and notify the main thread that a task has completed.
pool.assignedTasks--;
pool.joinCondition.notify_one();
}我用这个东西做物理模拟,这个东西发生在模拟的每一步(大约每16毫秒一次)。发生的情况是,在经过几百步之后,一切都停止了,因为在(主线程进入等待状态)之前以某种方式发送了通知信号(),可能是因为它正在检查条件。如果我进行调试,我可以看到计数器上还有一个任务,线程上没有运行的任务,队列中没有任务,也没有真正发生的事情。有时,更奇怪的是,一旦我用断点暂停执行并重新启动它,所有的东西就会解锁。我试过把更多的锁放在适当的位置,但没有用。有什么明显的东西我错过了吗?
UPDATE似乎通过将assignedTasks变量设置为volatile来解决问题。它经常被修改,有时寄存器中的值没有更新,一切都停止了。以前没必要这么做。哈。:)
发布于 2013-06-10 15:01:55
您正在使用两个不同的互斥(join_lock,pool.task_lock)在不同的时间“保护”assignedTasks -这是一个简单的老式种族条件。
https://stackoverflow.com/questions/17026503
复制相似问题