一、多线程QThread
主线程是QT程序启动时的线程,也叫UI线程,处理界面事务等。
子线程就是程序创建的其他线程,也叫逻辑线程。它的运行与界面UI无关。
可以有多个逻辑线程。只有一个UI线程。
主要包括以下功能
//状态判定
bool isFinished();//是否完毕
bool isRunning();//是否正在执行
//优先级
Priority QThread :: priority();//得到优先级
void QThread :: setPriority(Priority p);//设置优先级
线程优先级,默认最高。一菜有8级。低Idle/Lowest/Low/Normal/High/Highest/TimeCritical/Inherit高
退出与等待线程
void QThread :: exit(int retrun = 0);//退出
bool QThread :: wait(unsigned long time = UNLOG_MAX);//等待时间,默认无限等待。
quit();//与exit一样
start(优先级);
terminater();//立即退出,不建议使用
void QThread :: finished();//完成信号
void QThread :: started();//开始前发出信号,一般不用。
静态方法
currentThread();// 得到当前线程
idealThreadCount();//返回理想线程数据,与CPU核心相同。
//线程休眠方法
msleep(ulong msecs);//毫秒休眠
sleep(ulong secs);//秒休眠
usleep(usecs);//微秒休眠
//任务处理
run();//可重写函数
要线程做的事,主要写在run()重写的方法下面。完成了线程自动退出。标志isFinished=true.完成线程。
其他的方法和信号,可以自行到QT助手学习咨询。
QThread多线程使用方法
引用
#include<QThread>
//定义
方法一、写一个类,继承QThread类,重写run()方法.
class mythread:public QThread{
public :
void run();
}
mythread th=new mythread();
th.start();
在多线程中,有传送到UI线程的类型不支持。需要注册一下。在main函数中用qRegisterMetaType<类型>("类型")注册一下这种类型,之后就可以从子线程传送这类型的数据到UI线程了;//如QVector<int>
方法二、使用系统线程类创建线程,传入处理方法。
QThread * th= new QThread;
th.start();
QThread子类可以用MovtToThread(th)来放入线程运行。
二、线程池
QThreadPool
包括了相关属性
maxThreadCount();//最大线程量
setMaxThreadCount(int count);//设置最大线程量
加入线程任务QRunnabled对像。
void QThreadPool :: start(QRunnable * 对像,int 优先级);
bool QThreadPool :: tryStart(QRunnable * 对像);//判定能不能加入任务,因为要考虑池中有空闲线程可用。
int QThreadPool :: activeThreadCount();//正在工作的线程数量
bool QThreadPool :: tryTake(QRunnable * 对像);//尝试删除任务,如果已经启动就无法删除
void QThreadPool :: clear();//清空线程池的任务。
全局线程池对像
static QThreadPool * QThreadPool :: globalInstance();//各到一个QT程序的系统线程池对象
使用线程池的话,任务类必须继承QRunnable类。不然放不进线程池。
这个类有一个void run()方法可重写。
构造基本如下:
class myWork : public QObject,public QRunnable
{
Q_OBJECT
public :
explicit myWork(QObject * parent = nullptr)
{
//这句很重要
setAutoDelete(true);//自动销毁
}
~myWork();
void run() override{
//我们要重写这个类来对任务进行处理。
}
}
这样以后,以cpp里,就可以创建一个任务添加到系统线程池里
如下:
QThread :: globalInstance()->setMaxThreadCount(int n);
myWork task = new myWork;
QThread :: globalInstance()->start(task);
这样就完成了使用线程池的演示。