暂停QThread工作程序处理即将删除的资源的正确方法是什么?

时间:2013-07-12 21:55:44

标签: c++ multithreading qt thread-safety

这是一些伪代码来解释我的情况。我正在使用QThreads,但解决方案可能与Qt无关。

class ResourceOwner
{
  // Spawns worker on new QThread, initiates Worker::doWork()
 void spawnWorker(resource); {...}

 void deleteResourceSafely(); // How do you implement this function?

private:
 Resource *resource;
 Worker *worker;
}

class Worker
{
 void doWork() { while(true) resource->doSomething(); }
 void cleanupSelf() {...};
private:
 Resource *resource;
}

void main()
{
  ResourceOwner owner();
  owner.spawnWorker();
  ...
  // Some time later after enough work has been done
  owner.deleteResourceSafely();
}

当需要删除resource时,我们需要关闭工作人员。但是,Worker可能正在访问resource

如果刚删除resource,则Worker将崩溃,因为它会访问无效内存。我可以阻止Worker所属的主题,但Worker将无法正常清理自己。

所以我如何中断Worker的{​​{1}}功能,告诉它自我清理并停止访问doWork()

3 个答案:

答案 0 :(得分:1)

一种常见且简单的方法是让线程定期检查一个标志。如果已设置,则线程自行终止。

答案 1 :(得分:0)

鉴于您已经使用Qt,我建议尝试删除资源的线程应该向工作线程发送信号,然后等待工作线程因信号而终止。显然你需要实现一个合适的信号处理程序。

答案 2 :(得分:0)

如joachim所述,有一个标志,您定期检查工作线程。向Worker添加一个函数,称为requestStop,它将volatile bool或QAtomicInt设置为false,表示该线程应该退出run()。使用volatile bool确保编译器不会优化对它的访问。你的工作项应经常检查这个标志,如果它变为false,它应该确保它从run()asap返回。没有提到的是在设置标志后,在线程上调用wait()以使其退出。一旦调用wait()返回,线程就停止了,因此删除资源是安全的。

部分替代方法是使用引用计数资源来避免调用wait()。如果您的资源在工作线程中有一个指向它的共享指针,那么如果主线程删除对它的引用并标记线程(或工作项)以完成,则工作线程/项可以在完成时删除对它的引用并销毁如果它是唯一的剩余所有者。即这个aproach将适用于线程池,你不会等待线程完成,因为工作项排队了。