思考:1.线程的概念 2.为什么要使用线程 3.线程的分类及优劣比较
线程的概念
在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),可以并发执行,提高整体处理性能。
为什么要使用线程
1.提高程序运行的性能和用户体验。
2.充分利用CPU计算能力。
3.可以将耗时操作放在后台线程处理。
线程的分类及优劣比较
1.直接继承QThread,重载run()方法。
2.new一个QThread,将QObject对象通过moveToThread() 函数移入线程。
3.Qt 线程池。
方式一
class WorkerThread : public QThread
{
Q_OBJECT
void run() override {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &s);
};
void MyObject::startWorkInAThread()
{
WorkerThread *workerThread = new WorkerThread(this);
connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
workerThread->start();
}
优点:构造使用方式简单,所有操作都放在run()方法里面。
缺点:不够灵活,只能运行run()里面的程序。
方式二
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
优点:使用简单,可以使用信号槽通信,很灵活。
缺点:每次都要创建线程,带来不必要资源开支。
线程池 QThreadPool
优点:减少创建线程的时间和资源开销。
缺点:管理较复杂。
Qt程序有一个全局的线程池对象,可以用globalInstance()调用。
一、任务列表
class HelloWorldTask : public QRunnable
{
void run() override
{
qDebug() << "Hello world from thread" << QThread::currentThread();
}
};
HelloWorldTask *hello = new HelloWorldTask();
// QThreadPool takes ownership and deletes 'hello' automatically
QThreadPool::globalInstance()->start(hello);
QtConcurrent
优点:
1.高级多线程编程,可以不使用mutexes(互斥), read-write locks(读写锁), wait conditions(等待条件), or semaphores(信号量)。
2.可根据CPU数量,自动调整线程数量。
#include <QString>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include "qtconcurrentrun.h"
using namespace QtConcurrent;
void func(QString name)
{
qDebug() << name << "from" << QThread::currentThread();
}
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QFuture<void> fut1 = run(func, QString("Thread 1"));
QFuture<void> fut2 = run(func, QString("Thread 2"));
fut1.waitForFinished();
fut2.waitForFinished();
}