在写Qt过程中,目前会遇到大量数据处理,数据量200W以上,如果将处理数据操作在主线程中进行,会导致UI界面冻结,影响用户体验,所以将处理数据的过程迁移到子线程中是良好的处理手段,一般处理数据的对象都会定义为指针类型。代码如下:
/***************************************************************************
@date 2021-02-25
@author qiaowei
@contact [email protected]
@version 1.0
@brief 子线程,运行file_process_变量
***************************************************************************/
QThread file_process_thread_;
File_process* file_process_;
如果将对象迁移到子线程的步骤延后,就会有创建指针,迁移到子线程,创建指针,未迁移到子线程两种情况。代码如下:
void File_manager::start_thread(QThread& thread, QObject *process)
{
if ( !thread.isRunning()) {
process->moveToThread(&thread);
connect(&thread, &QThread::finished, process, &QObject::deleteLater);
thread.start();
}
}
void File_manager::sl_open_file_to_split_data()
{
QStringList opened_files = QFileDialog::getOpenFileNames();
if (opened_files.isEmpty()) {
return;
}
// 将处理文件数据对象迁入子线程,启动子线程
start_thread(file_process_thread_, file_process_);
emit si_files_name_of_split_data(opened_files);
}
void File_manager::sl_read_data_from_file()
{
QStringList opened_files = QFileDialog::getOpenFileNames();
if (opened_files.isEmpty()) {
return;
}
// 将处理文件数据对象迁入子线程,启动子线程
start_thread(file_process_thread_, file_process_);
emit si_files_name_of_readed_data(opened_files);
}
所以,如何避免内存泄漏,正确处理好指针变量,应该在类的析构函数中有所考量。Qt官方文档在构造函数中直接启动子线程,未将子线程延后:
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 &);
};
在处理延后子线程数据时,要考虑创建的指针对象存在的线程,如果在主线程,说明没有启动子线程,直接delete即可,如果不在主线程中,则不用手动处理,调用子线程方法,系统会自动处理。我的处理代码如下:
File_manager::~File_manager()
{
// 用户没有点击打开文件或拆分数据按钮,file_process_没有迁移到file_process_thread_线程中,需手动
// 释放资源
if (file_process_->thread() == thread()) {
delete file_process_;
file_process_ = nullptr;
}
file_process_thread_.quit();
file_process_thread_.wait();
}