一、线程体函数开启了事件循环,线程如何正常结束
1、QThread::exec()使得线程进入事件循环
(1)、事件循环结束前,exec()后的语句无法执行
(2)、quit()和exit()函数用于结束事件循环
(3)、quit() <---->exit(0),exec()的返回值由exit()参数决定
2、注意
(1)、无论事件循环是否开启,信号发送后会直接进入所依附线程的事件队列
(2)、然而,只有开启了事件循环,对应的槽函数才会在线程中被调用
二、什么时候需要开启事件循环
1、设计原则
(1)、事务性操作(间断性IO操作,等)可以开启线程的事件循环
(2)、每次操作通过发送信号的方式使得槽函数在子线程中执行
2、概念小科普:文件缓冲区(文件操作是事务性操作)
(1)、默认情况下,文件操作时会开辟一段内存作为缓冲区
(2)、向文件中写入的数据会先进入缓冲区
(3)、只有当缓冲区满或者遇到换行符时才将数据写入磁盘
(4)、缓冲区的意义在于:减少磁盘的低级IO操作,提高文件读写效率(但存在风险)
3、Qt线程的使用模式
(1)、无事件循环模式:后台执行常时间的耗时任务(文件复制、网络读取等)
(2)、开启事件循环模式:执行事务性操作(文件写入,数据库写入等)
开启一个线程,线程里边只需要开启事件循环,然后将槽函数,通过对象的依附性转移来将槽函数移到线程执行,最后不要忘了在析构函数中终止线程的执行
FileWrite.h
#ifndef FILEWRITE_H
#define FILEWRITE_H
#include <QObject>
#include <QFile>
#include <QString>
#include <QThread>
class FileWrite : public QObject
{
Q_OBJECT
private:
class writeThread : public QThread//记得是public继承
{
protected:
void run();
};
QFile* m_file;
writeThread thread;
public:
explicit FileWrite(QString path, QObject *parent = 0);
bool fileOpen();
void fileWrite(const char* text);
void fileClose();
signals:
void testWrite(const char* text);
void testClose();
protected slots:
void writeSlot(const char* text);
void closeSlot();
};
#endif // FILEWRITE_H
FileWrite.h
FileWrite.cpp
#include "FileWrite.h"
#include <QIODevice>
#include <QDebug>
FileWrite::FileWrite(QString path, QObject *parent) :
QObject(parent)
{
m_file = new QFile(path, this);
connect(this, SIGNAL(testWrite(const char*)), this, SLOT(writeSlot(const char*)));
connect(this, SIGNAL(testClose()), this, SLOT(closeSlot()));
moveToThread(&thread);//这句话极其重要,将槽函数移到线程中执行
thread.start();
}
bool FileWrite::fileOpen()
{
return m_file->open(QIODevice::WriteOnly | QIODevice::Text);
}
void FileWrite::fileWrite(const char* text)
{
emit testWrite(text);
}
void FileWrite::fileClose()
{
emit testClose();
}
FileWrite::~FileWrite()//析构函数中终止线程执行
{
thread.quit();
}
/**************************************槽函数******************************************/
void FileWrite::writeSlot(const char* text)
{
qDebug() << "void FileWrite::writeSlot(const char* text) tid = " << QThread::currentThreadId();
m_file->write(text);
m_file->flush();//每次写的时候都直接写入文件,进行低级的IO操作,比较耗时
}
void FileWrite::closeSlot()
{
qDebug() << "void FileWrite::closeSlot() tid= " << QThread::currentThreadId();
m_file->close();
}
/***********************************线程的函数*****************************************/
void FileWrite::writeThread::run()
{
qDebug() << "void FileWrite::writeThread::run() tid= " << QThread::currentThreadId();
exec();
}
FileWrite.cpp
main.cpp
#include <QtCore/QCoreApplication>
#include "FileWrite.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
FileWrite file("C:/Users/LGC/Desktop/test.txt");
if(file.fileOpen());
{
file.fileWrite("Hello word\n");
file.fileWrite("你好,世界\n");
file.fileWrite("狄泰软件学院,成就梦想\n");
file.fileClose();
}
return a.exec();
}
main.cpp
三、小结
(1)、QThread::exec()使得线程进入事件循环
(2)、quit() <---->exit(0)用于结束线程的事件循环并返回
(3)、事务性操作可以开启线程的事件循环,将操作分摊到子线程
(4)、工程开发中,多数情况不会开启线程的事件循环
(5)、线程多用于执行后台任务或者耗时操作