Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么是Qt for boost::promise<;T>;?_C++_Multithreading_Qt_Boost - Fatal编程技术网

C++ 什么是Qt for boost::promise<;T>;?

C++ 什么是Qt for boost::promise<;T>;?,c++,multithreading,qt,boost,C++,Multithreading,Qt,Boost,我看到Qt有一个直接模拟的类,但Qt的用途是什么?boost::promises是在未来设置值的方法。在Qt中,您不能设置期货,只能返回期货。这是未来“设置”数据的唯一方法 因此,为了设置未来的数据,您必须从QtConcurrent::run调用的函数返回数据。要做到这一点,您可以使用Qt的任何机制在线程之间进行通信——事件、互斥保护变量等。您必须告诉运行将返回未来的代码的线程,将返回给定的未来。这是实现承诺的唯一途径 唉,如果您想进入未记录的领域,那么下面的代码将执行boost::promis

我看到Qt有一个直接模拟的类,但Qt的用途是什么?

boost::promises是在未来设置值的方法。在Qt中,您不能设置期货,只能返回期货。这是未来“设置”数据的唯一方法

因此,为了设置未来的数据,您必须从
QtConcurrent::run
调用的函数返回数据。要做到这一点,您可以使用Qt的任何机制在线程之间进行通信——事件、互斥保护变量等。您必须告诉运行将返回未来的代码的线程,将返回给定的未来。这是实现承诺的唯一途径

唉,如果您想进入未记录的领域,那么下面的代码将执行
boost::promise::setValue
所做的操作:

QFuture<int> f;
int i = 1;
...
f.d.reportResult(&i);
// or
f.d.reportFinished(&i);
QFuture f;
int i=1;
...
f、 d.报告结果(&i);
//或
f、 d.报告完成(&i);

我还没有费心检查它是否有效。

按照公认的答案构建我自己的QFuture对我不起作用。起初,它看起来像是在工作,但在我的测试中,我意识到它并没有阻止调用方。哎呀!因此,我进一步深入研究了代码,发现QFutureInterface是您想要用作“承诺”的东西。像boost::promise一样,QFutureInterface是您在工作线程中与之交互的对象,它是QFutures的工厂

下面是我在Qt4.8中所做的工作(不确定这是否适用于更高版本)


future()
调用是一种工厂方法,用于创建绑定到QFutureInterface的QFuture。如果需要,您应该能够获得QFuture并在以后调用
result()

没有官方的Qt模拟,但有一些社区库实现了承诺(或类似模式):

  • 本·刘的未来()
    基于中提到的未记录的
    QFutureInterface

    这不完全是一种承诺模式,而是一种观察者模式
  • 贝诺伊特·沃尔特的承诺()
    部分基于本·刘的未来
  • 西蒙·布鲁内尔的承诺()
  • 我的承诺()
    免责声明:我是作者

Qt的承诺现在也可通过QML/JavaScript附带提供:

下面是一些示例代码:

import VPlayApps 1.0
import QtQuick 2.0

App {
  Component.onCompleted: {
    var p1 = Promise.resolve(3);
    var p2 = 1337;
    var p3 = HttpRequest
    .get("http://httpbin.org/get")
    .then(function(resp) {
      return resp.body;
    });

    var p4 = Promise.all([p1, p2, p3]);

    p4.then(function(values) {
      console.log(values[0]); // 3
      console.log(values[1]); // 1337
      console.log(values[2]); // resp.body
    });
  }
}

我创建了这个与Qt高度集成的库,并实现了类似javascript的承诺:

它允许创建线程安全的异步API,如下所示:

multiplyNumbersInThread(3, 4)
.fail([](int res) {
    Q_UNUSED(res);
    qDebug() << "multiplyPositiveNumbers failed!";
})
.done([](int res) {
    qDebug() << "multiplyPositiveNumbers succeded! Result :" << res;
});
multilynumbersinthread(3,4)
.失败([](整数分辨率){
Q_未使用(res);

qDebug()
d
成员的文档说明了
//警告:d指针没有文档记录,被认为是私有的。
,因此这可能不是一种方法。@JamesHenstridge如果您选择这样做,这是一种方法,但当然首选的解决方案在前面的段落中。使用
QFutureInterface
(就像在另一个答案中一样)如果没有一个Qt并发助手满足您的需求,则可能是更好的选择。它似乎被视为半公开的,并且最早在Qt 6之前不会改变:您应该提到您是此库的作者。另请参阅,即“避免公开自我推广”一段:“但是,您必须在回答中披露您的从属关系。”
import VPlayApps 1.0
import QtQuick 2.0

App {
  Component.onCompleted: {
    var p1 = Promise.resolve(3);
    var p2 = 1337;
    var p3 = HttpRequest
    .get("http://httpbin.org/get")
    .then(function(resp) {
      return resp.body;
    });

    var p4 = Promise.all([p1, p2, p3]);

    p4.then(function(values) {
      console.log(values[0]); // 3
      console.log(values[1]); // 1337
      console.log(values[2]); // resp.body
    });
  }
}
multiplyNumbersInThread(3, 4)
.fail([](int res) {
    Q_UNUSED(res);
    qDebug() << "multiplyPositiveNumbers failed!";
})
.done([](int res) {
    qDebug() << "multiplyPositiveNumbers succeded! Result :" << res;
});