Qt——线程的生命期问题

1.C++对象有生命周期,线程也有生命周期,QThread对象的生命周期与对应的线程生命周期是否一致?

2.工程实践中的经验准则

线程对象生命周期 > 对应的线程生命周期

MyThread.h

复制代码
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class MyThread : public QThread
{
    Q_OBJECT

protected:
    int i;

    void run();
public:
    explicit MyThread(QObject *parent = nullptr);
};

#endif // MYTHREAD_H

MyThread.cpp

复制代码
#include "MyThread.h"

MyThread::MyThread(QObject *parent)
    : QThread{parent}
{

}
void MyThread::run()
{
    this->i = 1;
    for(int i=0; i<5; i++)
    {
        this->i *= 2;
        sleep(1);
    }
}

main.cpp

复制代码
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "MyThread.h"
#include "SyncThread.h"

void test()
{
    MyThread t;
    t.start();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main() tid = " << QThread::currentThreadId();
    test();

    return QCoreApplication::exec();
}

运行结果:

main() tid = 0x2030

QThread: Destroyed while thread is still running

因为t已经被销毁,但是t中的run函数仍在执行

3.同步型线程设计

  • 线程对象主动等待线程生命期结束后才销毁
  • 同时支持在栈和堆中创建线程对象
  • 对象销毁时确保线程生命期结束

要点:在析构函数中先调用wait()函数,强制等到线程运行结束

使用场合:线程生命期相对较短的情形

SyncThreadh

复制代码
#ifndef SYNCTHREAD_H
#define SYNCTHREAD_H

#include <QThread>

class SyncThread : public QThread
{
    Q_OBJECT
protected:
    void run();
public:
    explicit SyncThread(QObject *parent = nullptr);
    ~SyncThread();
};

#endif // SYNCTHREAD_H

SyncThread.cpp

复制代码
#include "SyncThread.h"
#include <QDebug>

SyncThread::SyncThread(QObject *parent)
    : QThread{parent}
{

}
void SyncThread::run()
{
    qDebug() << "void SyncThread::run() tid = " << currentThreadId();

    for(int i=0; i<3; i++)
    {
        qDebug() << "void SyncThread::run() i = " << i;
        sleep(1);
    }

    qDebug() << "void SyncThread::run() end";
}

SyncThread::~SyncThread()
{
    wait();
    qDebug() << "SyncThread::~SyncThread() destroy thread object";
}

main.cpp

复制代码
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "MyThread.h"
#include "SyncThread.h"

void test()
{
    MyThread t;
    t.start();
}

void sync_thread()
{
    SyncThread st;
    st.start();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main() tid = " << QThread::currentThreadId();
    sync_thread();

    return QCoreApplication::exec();
}

运行结果:

main() tid = 0xe84

void SyncThread::run() tid = 0x3430

void SyncThread::run() i = 0

void SyncThread::run() i = 1

void SyncThread::run() i = 2

void SyncThread::run() end

SyncThread::~SyncThread() destroy thread object

4.异步型线程设计

  • 在run()中最后调用deleteLater()函数
  • 线程体函数主动申请销毁线程对象
  • 使用场合:线程生命期不可控,需要长时间运行于后台的情形

注意:deleteLater() 只对堆对象有效,对栈对象无效

AsyncThread.h

复制代码
#ifndef ASYNCTHREAD_H
#define ASYNCTHREAD_H

#include <QThread>

class AsyncThread : public QThread
{

    Q_OBJECT

protected:
    void run();
public:
    explicit AsyncThread(QObject *parent = 0);
    ~AsyncThread();
};

#endif // ASYNCTHREAD_H

AsyncThread.cpp

复制代码
#include "AsyncThread.h"
#include <QDebug>

AsyncThread::AsyncThread(QObject *parent) : QThread(parent)
{

}
void AsyncThread::run()
{
    qDebug() << "void AsyncThread::run() tid = " << currentThreadId();
    for(int i=0; i<3; i++)
    {
        qDebug() << "void AsyncThread::run() i = " << i;
    }
    qDebug() << "void AsyncThread::run() end";
    deleteLater();
}
AsyncThread::~AsyncThread()
{
    qDebug() << "AsyncThread::~AsyncThread() destroy thread object";
}

main.cpp

复制代码
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "MyThread.h"
#include "SyncThread.h"
#include "AsyncThread.h"

void test()
{
    MyThread t;
    t.start();
}

void sync_thread()
{
    SyncThread st;
    st.start();
}

void asyns_thread()
{
    AsyncThread *at = new AsyncThread();
    at->start();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug() << "main() tid = " << QThread::currentThreadId();
    asyns_thread();

    return QCoreApplication::exec();
}

运行结果:

main() tid = 0x2cf4

void AsyncThread::run() tid = 0x130c

void AsyncThread::run() i = 0

void AsyncThread::run() i = 1

void AsyncThread::run() i = 2

void AsyncThread::run() end

AsyncThread::~AsyncThread() destroy thread object

相关推荐
云和数据.ChenGuang1 小时前
Python 常见特殊方法详解:__new__、__init__、__del__、__str__、__repr__ 与 __getattribute__
开发语言·人工智能·python·1024程序员节
xyouyuweizhu1 小时前
字节流与字符流:Java IO 的两条主线该怎么选
java·开发语言·python
多弗朗皮卡丘2 小时前
C++的IO流
开发语言·c++·io流·文件io流
骑着蜗牛撵大象3272 小时前
AI Agent 工程化开发实战(三):用 StateGraph 给智能体搭一条可回放的状态流水线
java·开发语言·jvm·ai·状态管理·langgraph·stategraph
itmigrate2 小时前
Rust 里的所有权误区:不是不写 clone 就叫高性能
开发语言·后端·rust
Brilliantwxx3 小时前
【Linux】 文件访问与路径解析:目录、文件名、dentry、路径缓冲与 dcache 全解析
linux·运维·服务器·开发语言·spring
摇滚侠3 小时前
《On Java 中文版 基础卷》阅读笔记 初始化和清理 08
java·开发语言·笔记
xiangyun613 小时前
C++ 手撕 shared_ptr:引用计数与控制块到底长什么样?
开发语言·c++·算法·面试·stl
XiYang-DING3 小时前
P4009.和为K的子数组个数 & P5522.异或和为 k 的子数组个数
java·开发语言
jaysee-sjc4 小时前
【苍穹外卖】Day12:工作台数据看板与 Excel 报表导出
java·开发语言·数据库·spring boot·spring·微信·excel