继承QThread
继承QThread,通过重写虚函数void QThread::run()实现自己想做的操作,start()运行线程。
QThread::run()有一个默认的实现。这个默认实现其实是简单地调用QThread::exec()函数,而这个函数其实是开始了一个事件循环。
class WorkerThread : public QThread//继承QThread
{
Q_OBJECT
void run() Q_DECL_OVERRIDE {//
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &s);
};
WorkerThread *workerThread = new WorkerThread(this);//创建线程
workerThread->start();//开启线程
继承QRunnable
继承QRunnable,使用QThreadPool::globalInstance()->start() 运行它.
class Task : public QRunnable
{
//Q_OBJECT 注意了没有Q_OBJECT,Qrunnable不是QObject的子类。
public:
void run()
{
/* 线程的相关代码 */
}
};
Task runObj;
//QThreadPool::globalInstance()获得全局线程池
//start()将一个QRunnable对象放入QThreadPool的执行队列
//一旦有线程可用,线程池将会选择一个QRunnable对象,然后在那个线程开始执行.
QThreadPool::globalInstance()->start(&runObj);
要真正执行一个QRunnable对象,我们需要使用QThreadPool类。顾名思义,这个类用于管理一个线程池。通过调用QThreadPool::start(runnable)函数,我们将一个QRunnable对象放入QThreadPool的执行队列。一旦有线程可用,线程池将会选择一个QRunnable对象,然后在那个线程开始执行。所有 Qt 应用程序都有一个全局线程池,我们可以使用QThreadPool::globalInstance()获得这个全局线程池;与此同时,我们也可以自己创建私有的线程池,并进行手动管理。
需要注意的是,QRunnable不是一个QObject,因此也就没有内建的与其它组件交互的机制。为了与其它组件进行交互,你必须自己编写低级线程原语,例如使用 mutex 守护来获取结果等。
QThreadPool会自动的清理我们新建的Qrunnable对象.
moveToThread
使用moveToThread这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,
如果moveToThread里执行的函数没执行完,你是无法通过quit来结束的,必须使用第一种方法:最歹毒的一招mthread->terminate()强制退出。
为什么要使用moveToTread()呢。
eg:moveToThread对比传统子类化Qthread更灵活,仅需要把你想要执行的代码放到槽,movetothread这个object到线程,然后拿一个信号连接到这个槽就可以让这个槽函数在线程里执行。可以说,movetothread给我们编写代码提供了新的思路,当然不是说子类化qthread不好,只是你应该知道还有这种方式去调用线程。
class Dummy:public QObject
{
Q_OBJECT
public:
Dummy(QObject* parent=0):QObject(parent){}
public slots:
void emitsig()
{
emit sig();
}
signals:
void sig();
};
class Object:public QObject
{
Q_OBJECT
public:
Object(){}
public slots:
void slot()
{
qDebug()<<"from thread slot:" <<QThread::currentThreadId();
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"main thread:"<<QThread::currentThreadId();
QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread);
// 这里的slot()函数,相当于run()函数的作用,slot()函数将在线程中执行
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();
dummy.emitsig();
return a.exec();
}
QtConcurrent::run()
QtConcurrent::run()启动一个线程来执行一个函数.
QtConcurrent是一个命名空间而不是一个类,因此其中的所有函数都是命名空间内的全局函数。
QtConcurrent::run是个模板函数
void printMes(QString mes)
{
qDebug()<<"pprintMes thread : "<<QThread::currentThreadId();
qDebug()<<mes;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"mainthread :"<<QThread::currentThreadId();
QString mes = "hello world";
QtConcurrent::run(printMes,mes);
returna.exec();
}