阻塞 QFuture.result() 或 QFutureWatcher.waitForFinished();

Posted

技术标签:

【中文标题】阻塞 QFuture.result() 或 QFutureWatcher.waitForFinished();【英文标题】:Blocked QFuture.result() or QFutureWatcher.waitForFinished(); 【发布时间】:2014-08-19 21:18:41 【问题描述】:

所以我使用 QtConcurrent::run 已经有一段时间了,它很棒。但现在我需要该函数来返回一个对象。因此我使用伪代码

QFutureWatcher<MyObject> fw;
QFuture<MyObject> t1 = QtConcurrent::run(&thOb, &MythreadObjFunc::getList, ConSettings, form, query);
fw.setFuture(t1);
// Both .results() and waitForFinished() block
fw.waitForFinished();
MyObject entries = t1.result();

然后我遍历 myObject.问题是这会阻塞,例如我的主 GUI 没有响应。这就是我开始使用 QtConcurrent::run 的全部原因

因此,让我的 GUI 执行 QtConcurrent::run 并取回对象但不阻塞的推荐方法是什么?我想到了信号来自 QtConcurrent::run 的信号和槽,但这意味着它将来自不同的线程,我读到不推荐这样做。

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

您应该从不在 GUI 线程中使用任何 waitForFinished 函数。相反,将插槽连接到未来观察者的finished 信号。示例见this answer。

【讨论】:

【参考方案2】:

从 QtConcurrent::run() 你不能发出任何信号。 Runnable 函数不是 QObject。这是第一件事。

另一件事是 QFutureWatcher::waitForFinished() 会阻塞执行,直到线程结束执行。这是预期的行为。如果您必须等待函数完成,为什么还要在单独的线程上启动它?没有意义。

最简单的解决方案是让你的函数成为 QObject 继承类的成员,将实例移动到另一个线程,启动计算并发出 done() 信号。 Qt 的信号和槽系统是线程安全的,它是使用它的完美方式。 Qt 提供了一个出色的文档,足以涵盖这个主题。你应该从这里开始阅读:http://qt-project.org/doc/qt-4.8/threads.html

【讨论】:

以上是关于阻塞 QFuture.result() 或 QFutureWatcher.waitForFinished();的主要内容,如果未能解决你的问题,请参考以下文章

为啥非阻塞套接字在connect() 或accept() 之前是可写的?

linux C语言 ioctl()函数(修改socket_fd状态:阻塞或非阻塞)

阻塞非阻塞

多个 else if 阻塞或继续? [关闭]

此堆栈跟踪是不是以 _NtWaitForSingleObject@12() 结尾,表示线程阻塞或空闲?

使用 jQuery 检查元素是不是为“显示:无”或单击时阻塞