同步Qt中两个方法的线程执行

Posted

技术标签:

【中文标题】同步Qt中两个方法的线程执行【英文标题】:Sync the threaded execution of two methods in Qt 【发布时间】:2018-02-06 10:03:31 【问题描述】:

使用 Qt,我有两个 Worker 类实例(继承 QObject),每个实例使用 moveToThread 存在于自己的线程中。

Worker 类有一个 performOperation 方法,我使用以下方法从我的主线程调用:

QMetaObject::invokeMethod(workerLeft, "performOperation");

以便它在工作线程中运行。这很好,但我想在我的两个Worker 实例上并行运行performOperation,并在我的主线程中等待两者都完成。类似于同时拥有BlockingQueuedConnection

我尝试了不同的策略,使用QtConcurrent::runQFutureSynchronizer,如下所示:

QFuture<QString> runLeft = QtConcurrent::run(workerLeft, &Worker::performOperation);
QFuture<QString> runRight = QtConcurrent::run(workerRight, &Worker::performOperation);

QFutureSynchronizer<QString> sync;
sync.addFuture(runLeft);
sync.addFuture(runRight);

sync.waitForFinished();

但它不起作用,因为我在 Worker 中使用了 QTcpSocket,我在 performOperation 中使用它并且它失败了:

QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread

我已经能够通过在performOperation 方法中创建QTcpSocket 来使其工作,但我不喜欢这样,每次创建套接字都非常昂贵。

如果我可以选择QtConcurrent::run 应该在哪个线程中运行,我想我可以实现它,但我还没有找到任何类似的选项。

【问题讨论】:

您可以从您的工作人员发出信号,并在插槽中检查您是否收到两个信号,执行您的操作并将计数器设置为 0。 @AndrewKashpur 我想在两次调用之后立即阻塞主线程,这就是为什么我不考虑使用信号并手动携带计数器。 没有QtConcurrent 工作线程如何完成?有信号吗? 我在程序结束时手动处理线程的退出和删除。 @JoséTomásTocino,抱歉混淆了 .. 你说 ... 在我的主线程中等待两个都完成 .. 反正我在想一个本地 Eventloop。 【参考方案1】:

我认为有一个困惑: 1/ 如果你使用 QtConcurrent,基本上你让 Qt 管理所有与多线程相关的东西。在这种情况下,您不会在任何时候手动创建工作线程,也不会将对象移动到该工作线程,请参阅文档: http://doc.qt.io/qt-5/qtconcurrentrun.html

合约只是传递一个将在后台线程中执行的(staless)函数。这是一个高级并行编程 API。

2/ 如果你实现一个存在于工作线程中的工作对象,并且你想要同步,你必须使用其他方法,例如信号/槽或 QMutex。它是一个较低级别的线程 API,不能与 Concurrent 和 Future API 结合使用。

【讨论】:

以上是关于同步Qt中两个方法的线程执行的主要内容,如果未能解决你的问题,请参考以下文章

Java 并发 线程同步

同步主线程和工作线程

传统线程同步通信技术

Qt入门教程QObject篇线程同步

java并发传统线程同步通信技术

同步线程在不同类中执行代码的有效方法?