IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Qt线程启动的两种方法(QThread相关) -> 正文阅读

[C++知识库]Qt线程启动的两种方法(QThread相关)

多线程示例图

下图为多线程运行示例图,在输出界面回发现各个线程ID不相同,如次的话则线程创建运行成功
在这里插入图片描述

启动QThread的两种方法

  1. 通过继承QThread类的自定义线程类实现多线程
  2. 通过moveToThread方法实现多线程

废话少说上源码

方法一:

CThread.h

#ifndef CTHREAD_H
#define CTHREAD_H

#include <QObject>
#include <QThread>
class CThread : public QThread
{
    Q_OBJECT
public:
    explicit CThread(QObject *parent = nullptr);
    void run();	//在该函数种写想要执行的代码,使用当前类指针调用start函数运行
};
#endif // CTHREAD_H

CThread.cpp

#include "CThread.h"
#include <QDebug>

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

void CThread::run()
{
    while (true)
    {
        //输出当前函数和当前线程ID
        qDebug() << QThread::currentThreadId() << "我是线程ID, 继承线程类方法实现的";
        //设置线程睡眠一秒(单位为秒)
        QThread::sleep(1);
    }
}

方法二

CMoveFuncClass.h

#ifndef CMOVEFUNCCLASS_H
#define CMOVEFUNCCLASS_H

#include <QObject>

class CMoveFuncClass : public QObject
{
    Q_OBJECT
public:
    explicit CMoveFuncClass(QObject *parent = nullptr);

public slots:
    void doSomething();	//在该函数种写想要执行的代码,通过信号槽触发
};

#endif // CMOVEFUNCCLASS_H

CMoveFuncClass.cpp

#include "CMoveFuncClass.h"
#include <QDebug>
#include <QThread>

CMoveFuncClass::CMoveFuncClass(QObject *parent)
    : QObject(parent)
{
}

void CMoveFuncClass::doSomething()
{
    while (true)
    {
        //输出当前函数和当前线程ID
        qDebug() << QThread::currentThreadId() << "我是线程ID, moveToThread方法实现的";
        //设置线程睡眠一秒(单位为秒)
        QThread::sleep(1);
    }
}

调用类

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QMainWindow>
#include "CThread.h"
#include "CMoveFuncClass.h"

namespace Ui {
class CMainWindow;
}

class CMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit CMainWindow(QWidget *parent = 0);
    ~CMainWindow();

signals:
    void startMoveThread();

private slots:
    void on_startBtn_clicked();		//触发方法二函数的信号

private:
    Ui::CMainWindow *ui;

    CThread         *m_cThread;		//方法一指针

    CMoveFuncClass  *m_moveFunc;	//方法二指针

    QThread         *m_thread;		//方法二所移至的线程指针
};

#endif // CMAINWINDOW_H

CMainWindow.cpp

#include "CMainWindow.h"
#include "ui_CMainWindow.h"

#include <QDebug>

CMainWindow::CMainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::CMainWindow)
{
    ui->setupUi(this);

    /方法一///
    //new出CThread对象
    m_cThread = new CThread;
    
    /方法二///
    //new出CMoveFuncClass对象
    m_moveFunc = new CMoveFuncClass;
    //new一个moveToThread的接收线程并启动
    m_thread = new QThread;
    m_thread->start();  //一定记得启动,否则运行不了
    //连接相应信号槽
    connect(this, &CMainWindow::startMoveThread, m_moveFunc, &CMoveFuncClass::doSomething);
    connect(m_thread, &QThread::finished, m_moveFunc, &QObject::deleteLater);
    //将对象移至线程
    m_moveFunc->moveToThread(m_thread);
}

CMainWindow::~CMainWindow()
{
	delete m_cThread;
	delete m_moveFunc;
	delete m_thread;
    delete ui;
}

void CMainWindow::on_startBtn_clicked()
{
    //通过start启动方法一线程
    m_cThread->start();
    //发送信号启动方法二线程
    emit startMoveThread();

    //创建一个标记函数,限制循环次数
    int flag = 0;
    while(++flag != 5)
    {
        qDebug() << flag;
        //输出当前线程的线程ID
        qDebug() << QThread::currentThreadId() << "我是主类ID,创建和调用线程类的";
        //运行到当前位置睡眠一秒
        QThread::sleep(1);
    }
    //运行完成后推出两个线程并关闭窗口
    m_cThread->quit();
    m_cThread->wait(1);

    m_thread->quit();
    m_thread->wait(1);

    this->close();
}

注意:QThread::sleep在主线程使用时会导致主线程停止,如果设置的时间太长系统会当作是程序卡死,的情况,所以在主线程要么不使用sleep,要么在sleep时不操作程序窗口

总结

线程在很多时候是很有用的,当需要减少主线程负担时可以使用,需要后台重写某文件等情况可以使用,并且在线程运行时还不会影响主线程。当然了使用线程也得小心,如内存释放等问题,以及线程数量限制的问题(这里可以去了解线程池的用法)。

注:本文仅为作者编程过程中所遇到的问题和总结,并非代表绝对正确,若有错误欢迎指出。
注:如有侵权,联系作者删除

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 21:52:22  更:2022-03-17 21:55:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:48:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码