C++ 为正在运行的线程分配新线程是否安全? 背景
我有一个QObject(C++ 为正在运行的线程分配新线程是否安全? 背景,c++,multithreading,qt,C++,Multithreading,Qt,我有一个QObject(myClass),它在自己的线程中运行。UI可以在myClass中触发一个耗时的插槽。此插槽将处理内容、更新UI、处理更多内容,然后更新用于后台处理的变量。如果插槽的触发速度快于其处理速度,则第一次UI更新将很快发生,但后续更新将不得不等待(因为myClass仍在处理y()&z()) 为了克服这一问题,我使用了QtConcurrent::run进行缓慢的处理,以便后续更新也能快速更新UI(因为它们不必等待y()&z()) 问题 使用QMutexLocker时,重新分配正
myClass
),它在自己的线程中运行。UI可以在myClass
中触发一个耗时的插槽。此插槽将处理内容、更新UI、处理更多内容,然后更新用于后台处理的变量。如果插槽的触发速度快于其处理速度,则第一次UI更新将很快发生,但后续更新将不得不等待(因为myClass
仍在处理y()
&z()
)
为了克服这一问题,我使用了
QtConcurrent::run
进行缓慢的处理,以便后续更新也能快速更新UI(因为它们不必等待y()
&z()
)
问题
QMutexLocker
时,重新分配正在运行的QFuture
是否安全?声明它是安全的,但不包括互斥体QFuture
(如果是,是否可以重新启动,无论其状态如何,运行/完成/取消/暂停)y()
和z()
是线性的,而不是循环)假设上述代码是访问
future
变量的唯一位置。为了澄清,当y
和/或z
运行时,x
插槽可能会被触发,在这种情况下,您想取消y
/z
而运行x
?不同插槽之间是否存在依赖关系?“使用QMutexLocker时重新分配正在运行的QFuture安全吗?”在哪里使用了锁,在哪个互斥锁上?一般来说,future是结果的句柄,而不是线程本身,因此复制或销毁它不会影响操作本身。还请注意,无法取消run()的期货,请参阅QFuture::cancel()的文档(普通函数/lambda在一般情况下无法安全取消)@bnaecker对于混淆,非常抱歉slowProcess()
是插槽,其中x
,y
和z
是从插槽中调用的函数。当触发slowProcess()
时,它应该开始执行x
,而qthread可能仍在忙于执行对slowProcess()
的上一个调用,对这个新调用进行排队。(我已将slowProcess()
更新为mySlot()
)@FrankOsterfeld每次调用锁时都将使用相同的互斥锁,在y
、z
和myOtherSlot
内。只是澄清一下,“因此复制或销毁它不会影响操作本身”在第二季度可以解释为“是的,它们将继续在后台执行,直到执行完成或超时,即使未来已被重新分配”?澄清一下,当运行y
和/或z
时,可能会触发x
插槽,在这种情况下,您想取消y
/z
而运行x
?不同插槽之间是否存在依赖关系?“使用QMutexLocker时重新分配正在运行的QFuture安全吗?”在哪里使用了锁,在哪个互斥锁上?一般来说,future是结果的句柄,而不是线程本身,因此复制或销毁它不会影响操作本身。还请注意,无法取消run()的期货,请参阅QFuture::cancel()的文档(普通函数/lambda在一般情况下无法安全取消)@bnaecker对于混淆,非常抱歉slowProcess()
是插槽,其中x
,y
和z
是从插槽中调用的函数。当触发slowProcess()
时,它应该开始执行x
,而qthread可能仍在忙于执行对slowProcess()
的上一个调用,对这个新调用进行排队。(我已将slowProcess()
更新为mySlot()
)@FrankOsterfeld每次调用锁时都将使用相同的互斥锁,在y
、z
和myOtherSlot
内。只是澄清一下,“因此复制或销毁它不会影响操作本身”在第二季度可以解释为“是的,它们将继续在后台执行,直到执行完成或超时,即使未来已被重新分配”?
void myClass::mySlot() {
x(); // Fast
emit updateUI();
y(); // Slow
z(); // Slow
emit processingComplete();
}
void myClass::mySlot() {
x(); // Fast
emit updateUI();
// future is a member variable of myClass of type QFuture<void>
future = QtConcurrent::run([&]() {
y(); // Slow
z(); // Slow
emit processingComplete();
});
}
...
emit updateUI();
if(future.isRunning())
future.cancel();
future.waitForFinished()
future = QtConcurrent::run([&]() {
...