Qt多线程学习-用例子来理解多线程

Qt 多线程之线程事件循环(深入理解) QT多线程专栏共有14篇文章,从初识线程到、QMutex锁、QSemaphore信号量、Emit、Sgnals、Slot主线程子线程互相传值同步变量、QWaitCondition、事件循环、QObjects、线程安全、线程同步、线程异步、QThreadPool线程池等线程操作进行了全面!深入!的研究和详细的说明 阅读详情

POINT 1:QThread类的实例与普通类的实例没什么不同,只是运行着的run()函数会不同

例1:

 

class MThread :public QThread
{
public:
    MThread();
    ~MThread();
    void run();
    void foo();
    ...
    
};


class MDialog :public QDialog
{
    ...
    MThread *mythread;
};
MDialog::MDialog()
{
    mythread = new MThread;
    ... 
}
需要注意的是,在QT中,QThread对象的实例mythread是属于创建它的线程(线程A,即MDialog所在的线程)的,mythread的所有程序代码与数据都放在与MDialog相同的空间中.这时的mythread,就像任何普通的自己定义的类的实例一样.但是在调用mythread->start()之后,mythread的run()函数中的代码会在新的线程(线程B)中执行.在run()函数中声明的变量/实例化的对象,都属于线程B.但是mythread的所有代码,都还在存储在线程A中,只是run()函数的"执行"是在线程B中.

在MDialog中,使用

 

mythread->foo();
foo()是在线程A中执行的.

 

在MDialog中使用

 

connect(this, SIGNAL(sigDialogSignal()), mythread, SLOT(slotThreadSlot()));
当emit sigDialogSignal()时,是会在MDialog所在的线程A中执行的.因为mythread与MDialog同属于一个线程, 这时thread可以看做一个普通类的实例.另外,因为connect函数的连接方式默认是自动连接,而对同属于一个纯种的两个对象,自动连接会使用直接连接,即slot在发出signal的线程中立即执行.

 

例2:

 

#include "mthread.h"
#include <QDebug>
MThread::MThread(QObject *parent)
    : QThread(parent)
{
    myTimer.start(1);
    connect(&myTimer, SIGNAL(timeout()), this, SLOT(slotPrint()));
}

MThread::~MThread()
{

}

void MThread::run()
{   
    for (int i = 0; i < 100; ++i) {
        for (int j = 0 ; j < 10000; ++j) {
            qDebug()<<"---------"<<i;
        }
    }
    exec();
}

void MThread::slotPrint()
{
    qDebug()<<"==============================";

}
运行后出现:

 

...
...
---------9
==============================================================
---------9
...
...
不能误以为:在一个QThread类的派生类中,run()函数中的语句在运行时,可能被本线程定时器超时slot中断. (错误)

事实上,slotPrint()在创建MThread的实例的线程中执行.

 

POINT 2:线程B中的对象要想接收线程A中的对象发来的signal, 必须进入exec(), 如在exec()前有死循环, 没有进入exec(), 则线程B中的对象不会收到signal.

 

void MThread::run()
{
    while(1) {
        dosomething();  //此循环永不退出
    }
    exec();             //如果此事件循环不能进入,刚此线程不会收到任何signal
}
POINT 3:线程A中的指针可指向线程B中创建的对象实例,  这个实例属于线程B. 指针仅仅是一个地址, 而对象实例的变量/代码等都属于线程B.

例1:

 

class MThread : public QThread
{
    Q_OBJECT

public:
    MThread(QObject *parent = 0);
    ~MThread();
    void run();
    MPrint *mprint;
};
void MThread::run()
{
    mprint = new MPrint;
    exec();
}
//如此声明,mprint所指向的对象属于另一个线程.
例2:

 

class MThread : public QThread
{
    Q_OBJECT

public:
    MThread(QObject *parent = 0);
    ~MThread();
    void run();
    MPrint *mprint;
private:
    QTimer *myT imer;


private slots:
    void slotPrint();   
    void testFoo();
};

void MThread::run()
{
    myTimer = new QTimer;
    mprint = new MPrint;
    myTimer->setInterval(100);
    connect(myTimer, SIGNAL(timeout()), this, SLOT(testFoo()), Qt::DirectConnection);
    QTimer::singleShot(0, myTimer,SLOT(start()));
    exec();
}
以上这样写run(),myTimer在run()中new,即myTimer这个指针属于旧线程,但myTimer所指向的QTimer实例的实体在新的线程中,testFoo()会在新线程中执行.

例3:

 

void MThread::run()
{
    QTimer myTimer;
    mprint = new MPrint;
    myTimer.setInterval(100);
    connect(&myTimer, SIGNAL(timeout()), this, SLOT(testFoo()), Qt::DirectConnection);
    QTimer::singleShot(0, &myTimer,SLOT(start()));
    //testFoo();
    exec();
}
以上这样写run(),myTimer在run()中声明,即myTimer属于新的线程,testFoo()也会在新线程中执行.

例4:

 

class MThread : public QThread
{
    Q_OBJECT

public:
    MThread(QObject *parent = 0);
    ~MThread();
    void run();
    MPrint *mprint;
private:
    QTimer myTimer;


private slots:
    void slotPrint();   
    void testFoo();
};


void MThread::run()
{
    mprint = new MPrint;
    myTimer.setInterval(100);
    connect(&myTimer, SIGNAL(timeout()), this, SLOT(testFoo()));
    QTimer::singleShot(0, &myTimer,SLOT(start()));
    //testFoo();
    exec();
}
以上这样写run(),testFoo()会在创建myTimer的老线程中执行.因为可以看到,mytimer和this(即mythread),都是在同一个线程中,只是在另一个线程中(run()),做了connect操作.

要注意的是,在线程B中启动线程A中的一个定时器,不能使用myTimer.start(),这样启动不了定时器.而应使用signal来触发start()这个slot.


 

POINT 5:slot不会中断同线程中的slot.

例1:

 

#include "mthread.h"
#include <QDebug>
MThread::MThread(QObject *parent)
    : QThread(parent)
{
    myTimer.start(1);
    connect(&myTimer, SIGNAL(timeout()), this, SLOT(slotPrint()));
}

MThread::~MThread()
{

}

void MThread::run()
{
    exec();
}

void MThread::slotPrint()
{
    qDebug()<<"===========================";
    for (int i = 0; i < 100; ++i) {
        for (int j = 0 ; j < 10000; ++j) {
            qDebug()<<"---------"<<i;
        }
    }
}

slotPrint()函数运行完之后才会退出,说明slot不会中断slot,一个slot在执行完之后才会执行下一个slot.

注意:slotPrint()在创建MThread实例的线程中执行.而不是使用thread->start()创建出的那个线程.

例2:

 

#include "mthread.h"
#include <QDebug>
MThread::MThread(QObject *parent)
    : QThread(parent)
{
    myTimer.start(1);
    connect(&myTimer, SIGNAL(timeout()), this, SLOT(slotPrint()));
}

MThread::~MThread()
{ }

void MThread::run()
{
    testFoo();
    exec();
}

void MThread::slotPrint()
{
    qDebug()<<"=======================";

}

void MThread::testFoo()
{
    for (int i = 0; i < 100; ++i) {
        for (int j = 0 ; j < 10000; ++j) {
            qDebug()<<"---------"<<i;
        }
    }
}

以上代码中,slotPrint()与testFoo()会在两个不同的线程中执行.

 

12.1 Qt5多线程:多线程及简单实例 一个Qt5多线程的简单实例,工作线程类WorkThread继承自QThread类。 立即下载

相关推荐

拼团系统设计-人群标签的设计与思考

最近在学习一个拼团项目中涉及到的人群模块的设计,写下一些实现与思考。

wywcool的博客 971

Qt学习——电子时钟

中间的冒号是一秒闪烁一次 新建一个继承自QLCDNumber的类 头文件: #ifndef DIGICLOCK_H #define DIGICLOCK_H #include class DIgiClock : public QLCDNumber { Q_OBJECT public: DIgiClock(QWidget *parent = 0); void m

liming's blog 5416

EAST算法(Efficient and Accuracy Scene Text))

1.EAST模型简介 本文介绍的文本检测模型EAST,便简化了中间的过程步骤,直接实现端到端文本检测,优雅简洁,检测的准确性和速度都有了进一步的提升。如下图: 其中,(a)、(b)、(c)、(d)是几种常见的文本检测过程,典型的检测过程包括候选框提取、候选框过滤、bouding box回归、候选框合并等阶段,中间过程比较冗长。而(e)即是本文介绍的EAST模型检测过程,从上图可看出,其过程简化为只有FCN阶段(全卷积网络)、NMS阶段(非极大抑制),中间过程大大缩减,而且输出结果支持文本行、单词的多个角度

博客 9578

QT中的多线程(二)

<br /><br />在 Qt文档中,术语“可重入”与“线程安全”被用来说明一个函数如何用于多线程程序。假如一个类的任何 函数在此类的多个不同的实例上,可以被多个线程同时调用,那么这个类被称为是“可重入”的。假如不同的线程作用在同一个实例上仍可以正常工作,那么称之为 “线程安全”的。<br />大多数c++类天生就是可重入的,因为它们典型地仅仅引用成员数据。任何线程可以在类的一个实例上调用这样的成员函数,只要没有 别的线程在同一个实例上调用这个成员函数。举例来讲,下面的Counter 类是可重入的:<br

hufeng825的专栏 914

车规级非易失存储选型指南:从AEC-Q100到ISO 26262的可靠性设计

非易失存储器是电子系统中负责长期保存关键数据与代码的核心组件,其可靠性直接决定了系统的长期稳定运行能力。在汽车电子领域,这一要求被提升到了极致,必须满足严苛的车规级标准。从原理上看,存储器的数据保持能力、擦写寿命等关键参数在高温、振动等恶劣环境下会急剧衰减,因此需要专门的设计与验证。其技术价值在于保障车辆全生命周期的功能安全与数据完整性,避免因存储失效导致的安全隐患或频繁维护。应用场景涵盖从发动机控制单元、自动驾驶域控制器到智能座舱的各类电子控制单元。本文聚焦于车规级非易失存储的选型,深入解析AEC-Q10

weixin_30938149的博客 457

YOLOv8安防监控实战:跌倒/闯入/徘徊实时检测(附TensorRT加速+声光报警部署代码)

精准性:针对跌倒/闯入/徘徊的行为特征优化,准确率达89.3%,误报率低于5次/天;实时性:TensorRT加速到50+FPS,报警延迟<1秒,满足安防“黄金响应时间”;低成本:无需专用AI芯片,RTX 3060或Jetson Orin就能跑,硬件成本比传统方案低60%;易部署:代码全开源,提供从模型训练到硬件联动的完整流程,2天即可搭起原型系统。如果你的安防监控还在“漏报误报”“响应慢”,建议先从跌倒检测的姿态过滤改起——用100张样本测试,再集成TensorRT加速,90%能看到明显改善。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 678

Qt中多线程的使用

最近项目中提出了新的需求,需要采集和收集图片。因为是高速相机,按照帧率至少200FPS的速度计算的话,30秒时间的图片也就是6000帧,同时要保持尽量不掉帧。因此这个开发任务就有两个重点: 1、如何能够在收集图片的时候不掉帧,把30秒钟采集到的图片尽可能的采集和收集到; 2、在保存文件时,如何能够保证界面的及时响应,因为需要存放大量的图片,在只有一个线程工作的情况下,势必不能保持界面的良好响应

我只是一个单纯的2的博客 1万+

uniapp - 详细手机端h5网页调用手机摄像头进行二维码识别扫描,在uniapp的H5移动端微信网页平台中,在浏览器中调用手机扫码功能详细教程,识别二维码并获取扫描结果(完整示例源码,一键复制即用

uniapp,h5,手机端网页,H5手机网页,uniapp开发h5实现扫码功能,uniapp微信h5网页扫码sdk使用教程,uniapp h5网页如何实现浏览器扫码,uniapp扫码功能怎么兼容h5_uniapph5怎么做扫码功能,uniapp的手机网页如何实现扫二维码一维码,浏览器H5实现js扫码,H5调用摄像头和扫一扫功能,亲测可用,H5调用本地摄像头实现扫一扫,uni-h5项目解决扫码功能,uniapp实现微信H5扫码,解决uniapp在H5端使用不能扫码问题,uni-app的h5扫码(二维码、条形码

✅ 精选推荐文章 1万+

Qt多线程学习-用例子来理解多线程(转)

POINT 1:QThread类的实例与普通类的实例没什么不同,只是运行着的run()函数会不同 例1:   class MThread :public QThread  {  public:      MThread();      ~MThread();      void run();      void foo();      ...        };

myic211的专栏 531

9篇2章2节:GBD 数据库的数据申请详解

无论您是初入公共卫生领域的学生、资深的科研工作者,还是政策决策者,GBD数据库都将成为您数据分析与决策支持中不可或缺的重要工具。

MD Code 2598

目标检测YOLO实战应用案例100讲-基于数据融合的SAR图像中海上目标检测与跟踪(中)

本文使用的数据集为欧空局(European Space Agency, ESA)提供的Sentinal-1 数据集,Sentinel-1是欧洲“哥白尼计划”的SAR卫星机群,主要是用于陆地和海 洋服务的极地轨道全天候昼夜雷达成像任务[ 34]。Sentinel-1A于2014年4月3日发 射升空,Sentinel-1B于2016年4月25日发射升空,每颗卫星都携带C波段SAR, 共同提供地球表面的全天候、昼夜图像。

qq_36130719的博客 355

Qt多线程学习-用例子来理解多线程(转),这个是我看过最好的文章,总结很详细

01 class MThread :public QThread 02 { 03 public: 04 MThread(); 05 ~MThread(); 06 virtual void run(); 07 void foo(); 08 ... 09 10 }; 写在开头的话:本来查看的原文是转载,但是原文给

M_S_C的专栏 1536

【AI智能体】Codex 生成高质量电商套图实战操作详解

Codex 生成高质量电商套图实战操作详解

congge 4517

Qt例子合集:Qt学习者的宝藏资源库

Qt例子合集:Qt学习者的宝藏资源库 【下载地址】Qt例子合集 Qt例子合集是一个专为Qt学习者和开发者打造的综合性资源库,汇集了丰富且实用的编程实例。无论您是初学者还是资深开发者,都能在这里找到适合的案例,涵盖基础控件使用、常用对话框操作、图形特效处理、网络编程、数据库操作及多线程编程等典型场景。这些精选示例不仅具有高...

gitblog_06798的博客 443

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【免费下载】 掌握Qt编程的捷径:100个小练习例子

掌握Qt编程的捷径:100个小练习例子 【下载地址】Qt编程100个小练习例子 本仓库提供了100个Qt编程的小练习例子,旨在帮助初学者和有经验的开发者通过实践掌握Qt编程的核心概念和技巧。每个例子都设计得简洁明了,适合快速学习和实践。 ...

gitblog_09813的博客 976

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

【QT开发日志】QT多线程编程:实现高效的多线程应用

在当今的软件开发领域,用户对应用程序的性能和响应速度要求越来越高。尤其是在处理复杂任务、大量数据或进行网络通信时,单线程往往难以满足需求,容易出现界面卡顿、操作无响应等问题,严重影响用户体验。

鸽芷咕的博客 9776

【Qt学习】06 Qt多线程之QThread用法

多线程的优势 1、合理安排负载。对于图形界面程序尤其重要,当一个操作耗时很长,整个程序都会等待这个操作,程序就不能及时响应键盘鼠标等操作。多线程可以将耗时长的操作置于新的线程上,从而避免这个问题的发生。 2、提高系统效率。操作系统调度多线程任务运行到不同的CPU核心,从而避免系统资源浪费。 3、改善程序结构。一个既长又复杂的进程可以分解为多个线程,成为独立的运行部分,有利于代码的理解和维护。 环境 IDE:Qt creator 4.11.0 编译器:MinGW 5.3.0 32bit fo.

sunriver2000的专栏 1641
上一篇: linux串口编程
下一篇: mplayer 交叉编译
futurepeter
博客等级 码龄19年 8粉丝 1原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值