首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QFuture的自定义创建

QFuture的自定义创建
EN

Stack Overflow用户
提问于 2020-02-17 18:17:00
回答 2查看 497关注 0票数 1

我在QtConcurrent上遇到了一个很奇怪的问题,主要是因为奇怪的编程欲望,也许这只是一个XY问题,但是.

所以,这是我的代码,试图与数据库通信,实际上是后端代码(在Qt上,是的)。它必须快速工作并处理一些请求,所以我需要一个线程池。作为一个众所周知的事实,我认为建立自己的连接是一个非常耗时的操作,因此需要持久的数据库连接导致持久线程(QSqlDatabase不能在线程之间移动)。另外,需要异步请求处理也是很自然的,因此需要一种简单的方法将它们传递给持久线程。

没有什么太复杂的,让我们假设已经有一些样板存在于一种类似于.

代码语言:javascript
复制
// 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类来完成,但据我所知,某些“类似承诺”的解决方案使异步调用更加整洁。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-19 06:59:37

您可以使用AsyncFuture库作为自定义QFuture创建工具或想法源:

AsyncFuture --像使用承诺对象一样使用QFuture QFuture与QtConcurrent一起用于表示异步计算的结果。它是多线程编程的一个强大组件.但是它的使用仅限于线程的结果,它不适用于QObject发出的异步信号。通过QFutureWatcher设置侦听器函数有点麻烦。 AsyncFuture旨在增强该功能,为异步编程提供一种更好的使用方法。它提供了一个有希望的对象,如接口。这个项目受到AsynQt和RxCpp的启发。

特性:

  • 将来自QObject的信号转换为QFuture对象
  • 将具有不同类型的多种期货组合成一个单一的未来对象
  • 像承诺对象一样使用未来
  • 链式回调-高级多线程编程模型

将来自QObject的信号转换为QFuture对象:

代码语言:javascript
复制
#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";
});
票数 1
EN

Stack Overflow用户

发布于 2020-02-17 21:44:30

我的想法是使用最多为每个线程提供1个线程的线程池。

代码语言:javascript
复制
QThreadPool* persistentThread = new QThreadPool; // no need to write custom thread pool
persistentThread->setMaxThreadCount(1);
persistentThread->setExpiryTimeout(-1);

然后

代码语言:javascript
复制
QFuture<int> future_1 = QtConcurrent::run(persistentThread, func_1);
QFuture<int> future_2 = QtConcurrent::run(persistentThread, func_2);

func_2将在func_1之后在同一个“持久”线程中执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60268353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档