[Qt] QFuture和QFutureWatcher

来源:互联网 发布:问题跟踪软件 编辑:程序博客网 时间:2024/06/06 07:37

[Qt] QFuture和QFutureWatcher

QFuture, QFutureWatcher
第一次看到这两个类,感觉很有意思,也很有用。整理如下:

先来说说QFuture:
QFuture类代表了一个异步调用的结果。而这个异步调用需要使用Qt Concurrent架构中的API。
QFuture让线程可以通过某个后期产生的结果来实现同步。这个结果可以是任何拥有默认构造函数和拷贝构造函数的类型。如果这个结果在调用其result(), resultAt(), 或者 results()方法时还没有准备好,QFuture将会一直等到结果准备好。可以通过它的isResultReadyAt()方法来检测结果是否准备好。对于QFuture对象需要准备多个结果的情况,其resultCount()方法会返回连续结果的数量。这意味着从0遍历到resultCount()总是安全的。QFuture提供了Java类型的遍历器QFutureIterator以及STL类型的遍历器QFuture::const_iterator,可以根据自己的编程习惯使用它们来遍历结果。
QFuture提供了很多方法来跟正在进行的异步调用交互。例如可以通过其candel()方法来取消执行。可以通过setPaused(),pause(), resume(), 或者 togglePaused()来停止执行。这里需要注意不是所有的异步执行都可以取消或者停止。例如通过QtConcurrent::run()的future是不能被取消的,而通过QtConcurrent::mappedReduced()获得的future则可以被取消。

可以通过progressValue(), progressMinimum(), progressMaximum(), and progressText()方法来获得执行的进度信息。waitForFinished()方法会导致当前线程阻塞只到异步执行结束。

异步执行的状态信息可以通过isCanceled(), isStarted(), isFinished(), isRunning(), 或者 isPaused()方法来获得。

QFuture是一个轻量级的引用计数类,可以直接使用值传递方式。

QFuture<void>比较特殊,它表示不返回异步调用的结果。任何QFuture<T>对象都可以赋值或者拷贝给QFuture<void>对象。QFuture<void>对于结果数据不需要而只需要状态或者进度信息的情况比较有用。

如果想通过信号槽来跟异步调用实现交互,则要使用下面的QFutureWatcher。
 
QFutureWatcher是为QFuture而生的。通过QFutureWatcher我们可以通过信号槽来监视一个QFuture。

通过setFuture()方法可以开始监视一个QFuture。

为了方便,QFuture的很多方法我们可以直接通过QFutureWatcher来访问,如progressValue(), progressMinimum(), progressMaximum(), progressText(), isStarted(), isFinished(), isRunning(), isCanceled(), isPaused(), waitForFinished(), result(), and resultAt(). The cancel(), setPaused(), pause(), resume(), and togglePaused(),这些方法都是以槽的形式出现的。

下面我们来看一下SDK中给出的例子:
  1. //构造QFutureWatcher以及连接信号槽
  2. MyClass myObject;
  3. QFutureWatcher<int> watcher;
  4. connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));

  5. //开始异步调用
  6. QFuture<int> future = QtConcurrent::run(...);
  7. watcher.setFuture(future);
复制代码
上面这个例子本身没有问题。但我们经常会在类中使用QFutureWatcher,这时就要注意了,很多人在栈上构造QFutureWatcher,结果出问题了,qtcentre上就这么一个例子大家可以自己去看看:
http://www.qtcentre.org/threads/ ... -signal-not-working

原因很简单我就不说了
 



==================================
#include <QtCore>
// helloconcurrent/main.cpp
void hello()
{
    qDebug() << "Hello from thread " << QThread::currentThread();
}
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    ///重点分析下QFuture 和QtConcurrent这两个 关键字的用法!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    QFuture<void> future = QtConcurrent::run(hello);//thread-self自己函数就是一个线程.  暂时不懂QFuture和QtConcurrent的具体用法。
    qDebug() << "hello from GUI thread " << QThread::currentThread();
    future.waitForFinished();
    return 0;
}
原创粉丝点击