同步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::run
和QFutureSynchronizer
,如下所示:
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中两个方法的线程执行的主要内容,如果未能解决你的问题,请参考以下文章