说明
QThread:低级接口并且支持可选的时间循环
- QThread是多线程编程的基础类,QThread实例就是线程实例。
- QThread支持两种使用方式:
- 可以直接实例化QThread。
- 可以继承QThread,实例其子类。
实例化QThread(moveToThread方式)
- 该方式是官方推荐使用方式,实例化QThread提供了一个并行的事件循环,允许在其它线程通过信号的方式调用其内部函数。
- 使用流程:
- 定义一个继承QObject的类,如下:
* 头文件
class ThreadFunction : public QObject
{
Q_OBJECT
public:
Thread();
~thread();
void fun(int a);
};
* cpp文件
...
void ThreadFunction::fun(int a){
....
}
- 实例化QThread和将ThreadFunction对象moveToThread,如下:
QThread *Thread_Test = new QThread;
ThreadFunction *thread_class = new ThreadFunction;
thread_class->moveToThread(Thread_Test);
Thread_Test->start(); //开启线程
- 通过信号并行执行
connect(this,&MainWindow::ToThread, thread_class,&ThreadFunction::fun); //ToThread是定义的信号
emit ToThread(1);
继承QThread,实例其子类
- 子类化QThread允许程序在启动事件循环之前初始化新线程,但是没有事件循环,适合于需要循环执行的任务。
- 使用流程:
- 继承QThread类,并重写run函数,如下:
class TestThread : public QThread
{
Q_OBJECT
public:
TestThread(const QString &s, QObject *parent);
protected:
void run() override;
private:
....;
};
* cpp
...
void TestThread::run(){
while(1){
....;
}
}
- 创建线程并启动
TestThread *t = new TestThread("test", this);
t->start();
QThreadPool + QRunnable : 重复使用的线程
- 为了减少频繁的创建和销毁线程的开销,可以使用QThreadPool(线程池)+ QRunnable(任务实例)的方式。
- 使用流程:
- 定义QRunnable子类,并重写run函数,如下:
class LoginRunnable: public QRunnable
{
public:
LoginRequestRunnable();
protected:
void run() override;
};
void LoginRunnable::run(){
....;
}
- 创建QThreadPool实例或者使用全局线程池
- 全局线程池会根据CPU的核心数自动维护最佳线程数。
QThreadPool::globalInstance();
- 创建QRunnable子类实例,并放入QThreadPool中执行。
LoginRunnable *login = new LoginRunnable();
QThreadPool::globalInstance()->start(login);
线程交互
- 使用线程池的方式,如果需要和其它线程交互,有两种方式,如下:
- QMetaObject::invokeMethod方式
* 构建QRunnable子类对象时传入object对象
class QMyRunnable : public QRunnable
{
public:
QMyRunnable(QObject* obj);
protected:
void run();
private:
QObject* obj;
};
* 定义信号接收槽函数
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private slots:
void Update_Result(QString);
private:
....;
};
QMyRunnable *login = new QMyRunnable(this)
* 在QRunnable子类对象run函数中执行QMetaObject::invokeMethod
void QMyRunnable::run()
{
....;
QString str = QString("%1+%2=%3").arg(1).arg(1).arg(1+1);
QMetaObject::invokeMethod(obj,"Update_Result",Q_ARG(QString,str));
}
- 信号/槽方式
- 定义任务类既继承QRunnable也继承QObject,如下:
class QMyRunnable : public QRunnable, public QObject
{
Q_OBJECT
public:
QMyRunnable(QObject* obj);
protected:
void run();
private:
QObject* obj;
};
Concurrent : 高级接口
WorkerScript : QML编程中使用的线程
注意