我在QtConcurrent上遇到了一个很奇怪的问题,主要是因为奇怪的编程欲望,也许这只是一个XY问题,但是.
所以,这是我的代码,试图与数据库通信,实际上是后端代码(在Qt上,是的)。它必须快速工作并处理一些请求,所以我需要一个线程池。作为一个众所周知的事实,我认为建立自己的连接是一个非常耗时的操作,因此需要持久的数据库连接导致持久线程(QSqlDatabase不能在线程之间移动)。另外,需要异步请求处理也是很自然的,因此需要一种简单的方法将它们传递给持久线程。
没有什么太复杂的,让我们假设已经有一些样板存在于一种类似于.
// That's what I want for now
QFuture<int> res = workers[i]->async(param1, param2);
// OR
// That's what I DO NOT want to get
workers[i]->async(param1, param2, [](QFuture<int> res) { // QFuture to pass exceptions
// callback here
});这是可以肯定的。为什么不是std::future?好吧,使用QFutureWatcher要容易得多,而且它是通知结果准备就绪的信号。纯C++通知解决方案更复杂,回调也需要在类层次结构中拖放。显然,每个工作人员都将一个线程与DB连接进行接口。
好吧,所有这些都可以写出来,但是.自定义线程池意味着不方便QtConcurrent,似乎只有危险的方法来创建该QFuture,以便由自定义工作人员返回。QThreadPool没有任何用处,因为在其中创建持久的可运行程序将是一个很大的故事。更重要的是,我简要描述的样板将是某种项目的核心,在许多地方使用,而不是很容易被100个手工线程管理所取代。
简而言之:如果我能为我的结果分析一个QFuture,这个问题就会解决。有人能给我找个解决办法或解决办法吗?如果有什么好主意我会很感激。
UPD:
@VladimirBershov提供了一个很好的现代解决方案,实现了观察者模式。在谷歌上搜索了一下之后,我找到了一个QPromise库。当然,构建自定义QFuture仍然很麻烦,只能通过无文档的QFutureInterface类来完成,但据我所知,某些“类似承诺”的解决方案使异步调用更加整洁。
发布于 2020-02-19 06:59:37
您可以使用AsyncFuture库作为自定义QFuture创建工具或想法源:
AsyncFuture --像使用承诺对象一样使用QFuture QFuture与QtConcurrent一起用于表示异步计算的结果。它是多线程编程的一个强大组件.但是它的使用仅限于线程的结果,它不适用于QObject发出的异步信号。通过QFutureWatcher设置侦听器函数有点麻烦。 AsyncFuture旨在增强该功能,为异步编程提供一种更好的使用方法。它提供了一个有希望的对象,如接口。这个项目受到AsynQt和RxCpp的启发。
特性:
将来自QObject的信号转换为QFuture对象:
#include "asyncfuture.h"
using namespace AsyncFuture;
// Convert a signal from QObject into a QFuture object
QFuture<void> future = observe(timer, &QTimer::timeout).future();
/* Listen from the future without using QFutureWatcher<T>*/
observe(future).subscribe([]() {
// onCompleted. It is invoked when the observed future is finished successfully
qDebug() << "onCompleted";
},[]() {
// onCanceled
qDebug() << "onCancel";
});发布于 2020-02-17 21:44:30
我的想法是使用最多为每个线程提供1个线程的线程池。
QThreadPool* persistentThread = new QThreadPool; // no need to write custom thread pool
persistentThread->setMaxThreadCount(1);
persistentThread->setExpiryTimeout(-1);然后
QFuture<int> future_1 = QtConcurrent::run(persistentThread, func_1);
QFuture<int> future_2 = QtConcurrent::run(persistentThread, func_2);func_2将在func_1之后在同一个“持久”线程中执行。
https://stackoverflow.com/questions/60268353
复制相似问题