0

这是一些伪代码来解释我的情况。我正在使用 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没有机会正确清理自己。

那么我该如何中断函数WorkerdoWork()告诉它自己清理并停止访问resource呢?

4

3 回答 3

1

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

于 2013-07-12T21:58:12.797 回答
0

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

于 2013-07-12T22:08:31.377 回答
0

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

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

于 2013-07-12T22:35:25.033 回答