前面的博文中,我们讲过QtConcurrent模块,该模块是Qt中实现并发编程的高级API接口,而QRunnable结合QThreadPoll和QThread都是Qt中与并发编程相关的低级接口。今天我们先来看QRunnable和QThreadPool。
QRunnable类在Qt中是所有可运行对象的基类,代表了由run()函数表示的一个任务或一段要执行的代码。我们一般使用该类和QThreadPool来在另一个独立的线程中执行该代码。并且,如果QRunnable对象的autoDelete()设为true的话,QThreadPool会在run()运行结束后自动删除该对象。
下面,我们写一个例子,来使用一下该类。
新建一个Qt控制台程序,然后写一个派生自QRunnable的类,并重新实现其中的纯虚函数run()即可。
-
#ifndef RUNNABLE_H
-
#define RUNNABLE_H
-
#include <QRunnable>
-
-
class Runnable :
public QRunnable
-
{
-
public:
-
Runnable();
-
void run();
-
};
-
-
#endif // RUNNABLE_H
-
#include “runnable.h”
-
#include <QDebug>
-
#include <QThread>
-
-
Runnable::Runnable()
-
{
-
-
}
-
-
void Runnable::run()
-
{
-
qDebug() <<
“child thread id: “ << QThread::currentThreadId();
-
int i =
10;
-
while(i–)
-
{
-
qDebug() << QString(
“hello world %1”).arg(i);
-
}
-
}
然后在main函数中,使用QThreadPool来启动一个Runnable对象,在独立的线程中运行。
-
#include <QCoreApplication>
-
#include "runnable.h"
-
#include <QThreadPool>
-
#include <QDebug>
-
#include <QThread>
-
-
int main(int argc, char *argv[])
-
{
-
QCoreApplication a(argc, argv);
-
-
qDebug() <<
"main thread id: " << QThread::currentThreadId();
-
Runnable *r =
new Runnable();
-
QThreadPool::globalInstance()->start(r);
-
//QThreadPool::globalInstance()->waitForDone();
-
qDebug() <<
"end";
-
-
return a.exec();
-
}
其运行结果如下:
根据打印的thread ID可知,这些输出是由两个的线程的输出的,并且“end”先与子线程输出。如果我们想等到子线程运行完成再输出“end”,只需将代码中注释的那句打开即可。
运行结果如下:
此时,“end”就在子线程运行完成后才输出,即我们等待了线程的结束。
我们还可以实现一个析构函数,来验证QThreadPool是否为我们释放了Runnable对象。
-
Runnable::~Runnable()
-
{
-
qDebug() <<
"deleted";
-
}
在此执行程序,输出如下:
因为QRunnable的autoDelete属性默认为true,所以QThreadPool会在run()函数运行结束后,自动帮我们删除了Runnable对象。如果我们在main函数中,创建出Runnable对象后,修改该属性为false,那么将看不到“deleted”,因为此时Runnable对象的释放工作,将由我们自己来负责。
</div>
前面的博文中,我们讲过QtConcurrent模块,该模块是Qt中实现并发编程的高级API接口,而QRunnable结合QThreadPoll和QThread都是Qt中与并发编程相关的低级接口。今天我们先来看QRunnable和QThreadPool。
QRunnable类在Qt中是所有可运行对象的基类,代表了由run()函数表示的一个任务或一段要执行的代码。我们一般使用该类和QThreadPool来在另一个独立的线程中执行该代码。并且,如果QRunnable对象的autoDelete()设为true的话,QThreadPool会在run()运行结束后自动删除该对象。
下面,我们写一个例子,来使用一下该类。
新建一个Qt控制台程序,然后写一个派生自QRunnable的类,并重新实现其中的纯虚函数run()即可。
-
#ifndef RUNNABLE_H
-
#define RUNNABLE_H
-
#include <QRunnable>
-
-
class Runnable :
public QRunnable
-
{
-
public:
-
Runnable();
-
void run();
-
};
-
-
#endif // RUNNABLE_H
-
#include “runnable.h”
-
#include <QDebug>
-
#include <QThread>
-
-
Runnable::Runnable()
-
{
-
-
}
-
-
void Runnable::run()
-
{
-
qDebug() <<
“child thread id: “ << QThread::currentThreadId();
-
int i =
10;
-
while(i–)
-
{
-
qDebug() << QString(
“hello world %1”).arg(i);
-
}
-
}
然后在main函数中,使用QThreadPool来启动一个Runnable对象,在独立的线程中运行。
-
#include <QCoreApplication>
-
#include "runnable.h"
-
#include <QThreadPool>
-
#include <QDebug>
-
#include <QThread>
-
-
int main(int argc, char *argv[])
-
{
-
QCoreApplication a(argc, argv);
-
-
qDebug() <<
"main thread id: " << QThread::currentThreadId();
-
Runnable *r =
new Runnable();
-
QThreadPool::globalInstance()->start(r);
-
//QThreadPool::globalInstance()->waitForDone();
-
qDebug() <<
"end";
-
-
return a.exec();
-
}
其运行结果如下:
根据打印的thread ID可知,这些输出是由两个的线程的输出的,并且“end”先与子线程输出。如果我们想等到子线程运行完成再输出“end”,只需将代码中注释的那句打开即可。
运行结果如下:
此时,“end”就在子线程运行完成后才输出,即我们等待了线程的结束。
我们还可以实现一个析构函数,来验证QThreadPool是否为我们释放了Runnable对象。
-
Runnable::~Runnable()
-
{
-
qDebug() <<
"deleted";
-
}
在此执行程序,输出如下:
因为QRunnable的autoDelete属性默认为true,所以QThreadPool会在run()函数运行结束后,自动帮我们删除了Runnable对象。如果我们在main函数中,创建出Runnable对象后,修改该属性为false,那么将看不到“deleted”,因为此时Runnable对象的释放工作,将由我们自己来负责。
</div>