qt多线程
前置:
主线程:UI线程,窗口事件处理,窗口控件数据更新。
子线程:后台业务处理,子线程不对窗口对象做任何处理,这些事情交给主线程
主线程,子线程进行数据传递使用信号槽
QThread
QThread Class 属于core. 父QObjecr
一些方法
常用成员函数:
QThread::QThread(QObject * parent = Q_NULLPTR);//参数为父对象,对象树,资源清理
bool QThread::isFinished() const;//判断线程任务是否处理完毕
bool QThread::isRunning() const;//判断线程是否在执行任务
Priority QThread::priority() const;//读取优先级
void QThread::setPriority(Priority priority);//设置优先级
void QThread::exit(int returnCode = 0);//线程退出,直接退(后续还有部分资源处理)
bool QThread::wait(unsigned long time = ULONG_MAX);//线程退出,等待任务完成
信号槽
槽函数:
void QThread::quit();//和exit效果一样,之后在调用wait()
void QThread::start(Priority priority = InheritPriority);//启动子线程
void QThread::terminate();//直接终止线程
信号:
void QThread::finished();//线程任务执行完毕发出
void QThread::started();//线程开始工作前发出
静态函数:
QThread *QThread::currentThread();//返回一个指向当前管理线程的指针。
int QThread::idealThreadCount();//在当先系统上运行的理想线程数,即cpu核心数
void QThread::msleep(unsigned long);//休眠
void QThread::sleep(unsigned long);//休眠
void QThread::usleep(unsigned long);//休眠
任务处理函数(virtual protected类型)
void QThread::run();//子类继承并重写,通过start()启动
使用:
第一种:
1.创建子类,继承QThread类
2.重写run方法
3.主线程中创建子线程对象
举例:MyThread * sunThread = new MyThread;
4.启用start()方法,启动子线程。
注:
*子线程创建出来后,父子间通信可以使用信号槽方式
*Qt中,子线程不要操作程序中的窗口类型对象,不允许,操作了程序就挂了
*主线程才能操作窗口类型对象
第二种:
1.创建子类,继承QObject类
2.在该类中添加公共的成员函数,作为子线程的业务逻辑。
举例:
public:
void working();
3.在主线程中创建一个QThread对象(这就是子线程的对象)
举例:
QThread * sub = new QThread;
4.在主线程中创建工作的类对象(不要给创建的对象指定父对象)
举例:
MyThread * work = new MyWork(this);//error
MyThread * work = new MyWork();
5.将工作类的对象移动到创建的子线程对象中,需要调用QObject类提供的moveToThread()方法
举例:
work->moveToThread(sub);//如果给work指定了父对象,就调用失败
6.启动子线程,调用start(),这时候线程启动,但是移动到线程内的对象并没有开始工作。
7.调用MyWork类对向的工作函数,让这个函数开始执行,这时候是在移动到的那个子线程中运行的。
注:
线程资源销毁:
第一种:创建线程对象时指定父对象(对象树)
第二种:检测主线程的析构信号
举例:
connect(this, &MainWindow::destroy, this, [=](){
t1->quit();
t1->wait();
t1->deleteLater();//封装了delete t1;
}
线程池的使用:
QThreadPool:
//获取和设置线程池中的最大线程个数:
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);
//给线程池添加任务,为QRunnable类型
//如果线程池中没有空闲线程了,任务会放到任务队列中,等待线程处理
void QThreadPool::start(QRunnable * runnable, int priority = 0);
bool QThreadPool::tryStart(QRunnable * runnable);//如果线程池中没有空闲线程了,任务添加失败,不会添加到任务队列
int QThreadPool::activeThreadCount() const;//正在工作的线程个数
bool QThreadPool::tryTake(QRunnable * runnable);//尝试删除线程池中的某个任务,如果任务已经开始,则无法删除
void QThreadPool::clear();//删除线程池中所有没有开始的任务
static QThreadPool* QThreadPool::globalInstance();//获取线程池的全局对象
QRunnable(线程池的任务对象类):
(纯虚)void QRunnable::run();//任务的执行流程,必须重写
void QRunnable::setAutoDelete(bool autoDelete);//设置线程任务结束后,任务对象是否自动销毁。
bool QRunnable::autoDelete() const;//获取任务对象的析构方式,是否自动销毁
注:
设置自动销毁后,无需在手动释放线程对象资源