为了避免阻塞UI线程,我在Qt中将一些I/O代码移到了QRunnable
中。这将以一些排队的插槽进行回调以指示其进度。
但是我最近看到了一些问题,当QRunnable
的所有者被销毁时,它无法删除可运行对象,直到其完成(否则崩溃,因为工作线程仍在使用它)。为了解决这个问题,我想在可运行对象中添加一个“WaitForFinished
”,它将在dtor中调用它,因此我可以简单地删除QRunnable
并知道它会阻塞,直到它在dtor退出之前完成。
我认为这应该很容易,因为我需要做的就是在QMutex
实现中使用QRunnable::run
,然后在WaitForFinished
中获取该互斥量。但是,这有一个竞赛条件,我不确定该如何解决。
考虑以下:
QRunnable
排队等待执行。 QRunnable
开始执行,但尚未将QRunnable::run
称为QRunnable
的WaitForFinished
,并在QMutex
之前获取QRunnable::run
-因此我们假设其未运行或未完成运行并破坏了QRunnable
,但它甚至还没有开始! 最佳答案
首先,没有一个适合所有解决方案的尺寸。首选方法将取决于任务详细信息。尽管我问了一些问题,但仍然存在很多歧义。但是,我将描述我能想到的最简单的方法。
startedJobsCounter
并增加它。 finishedJobsSem
。 waitForFinished
看起来像finishJobsSem.aquire(startedJobsCounter);
finishedJobsSem
。 startedJobsCounter
读写之间没有竞争,因为它们都是在所有者的对象线程中执行的。由于所有作业都将在销毁所有者对象之前完成,因此
finishedJobsSem
不能无效地使用可运行格式。