Qt中线程的简单使用

对于线程过去写的比较少,现在也几乎是小白的水平。先创建Qt empty project,即Qt空项目,打开QtCreate->文件->新建文件或项目->其它项目->empty qmke project,接着按提示创建Qt空项目,创建之后,在项目上右键添加新文件,选择源文件,创建main.cpp文件,添加如下代码:
main.cpp

#include <QtCore>int main(int argc,char* argv[])
{QCoreApplication app(argc,argv);return app.exec();
}

再添加新文件,选择类,基类为QThread,类名为myThread,最后添加代码后文件内容为:
myThread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QThread>class myThread : public QThread
{Q_OBJECT
public:explicit myThread(QObject *parent = nullptr);
protected:void run();
private:
//    volatile bool stopped;
};#endif // MYTHREAD_H

myThread.cpp

#include "mythread.h"
#include "Counter.h"
#include <QDebug>myThread::myThread(QObject *parent):QThread(parent)
{
//    stopped = false;
}void myThread::run()
{Counter counter;quint8 i = 4;while(i--){counter.increment();
//        int n = counter.GetValue();
//       qDebug()<<QString("n:").arg(counter.GetValue());qDebug()<<"n:"<<counter.GetValue();}
}

再添加另一个线程类,同样在项目上右键添加新文件,选择类,类名mythreadread,基类为QThread,创建好这个类之后,添加完代码之后,文件内容如下:
mythreadread.h

#ifndef MYTHREADREAD_H
#define MYTHREADREAD_H#include <QThread>class mythreadread : public QThread
{Q_OBJECT
public:explicit mythreadread(QObject *parent = nullptr);
protected:void run();
};#endif // MYTHREADREAD_H

mythreadread.cpp

#include "mythreadread.h"
#include "Counter.h"
#include <QDebug>mythreadread::mythreadread(QObject *parent):QThread(parent)
{}void mythreadread::run()
{Counter counter;quint8 i = 4;while(i--){counter.decrement();qDebug()<<"n="<<counter.GetValue();}
}

以上两个线程类创建完成之后,在项目上右键添加新文件Counter.h,即添加头文件,添加之后,修改其代码如下:
Counter.h

#ifndef COUNTER_H
#define COUNTER_Hclass Counter
{
public:Counter():n(0){}void increment(){n++;}void decrement(){n--;}int GetValue()const{return n;}//该函数不能修改类成员变量的值
private:int n;
};
#endif // COUNTER_H

现在在main函数中修改代码如下:
main.cpp

#include <QtCore>
#include "mythread.h"
#include "mythreadread.h"myThread thread1;
mythreadread thread2;int main(int argc,char* argv[])
{QCoreApplication app(argc,argv);//针对各自线程中的特定对象的成员操作,互不影响thread1.start();thread1.wait();thread2.start();thread2.wait();return app.exec();
}

运行程序,结果如下:
n: 1
n: 2
n: 3
n: 4
n= -1
n= -2
n= -3
n= -4
结论:第一个线程启动后,在其线程函数中创建了Counter的类对象,并循环调用四次Counter类的加计数函数,然后输出每一次加计数后的值,最后调用wait()函数等待线程的结束,第一个线程结束之后,启动第二个线程,在该线程中对Counter类的成员变量减计数,并输出每一次减计数后的值,最后等带线程二结束之后,主程序关闭。其中有三个点需要注意:

  1. 在Counter类的定义中,将函数的声明与定义放在了同一个文件Counter.h中。需要注意的是,在同一个文件中定义并声明一个类时,函数的定义不能在该类外,否则会出现错误提示,重定义该文件。像下面所写一样:
#ifndef COUNTER_H
#define COUNTER_Hclass Counter
{
public:Counter():n(0){}int GetValue();
private:int n;
};
void Counter::GetValue()
{return n;
}
#endif // COUNTER_H

这样在类中定义成员函数,会导致编译错误,只能在类中进行定义。

#ifndef COUNTER_H
#define COUNTER_Hclass Counter
{
public:Counter():n(0){}int GetValue(){return n;}
private:int n;
};#endif // COUNTER_H
  1. 引入可重入的概念,一个类可以被多个线程使用,但每一次只能是调用该类自己的成员函数或成员变量。上面两个线程,在run()函数中分别对Counter类的成员函数进行操作,针对的是每一个Counter类自己的成员函数的操作,所以两个线程之间没有涉及到数据共享,线程同步等问题,可以线程实际是独立的。
  2. 如果将main.cpp中主函数中的两个线程的启动顺序变为如下:
   	thread1.start();thread2.start();thread1.wait();  thread2.wait();

那么程序的运行结果是怎么样呢?其运行结果如下:
n: 1
n= -1
n: 2
n= -2
n: 3
n= -3
n: 4
n= -4
可以看出,两个线程几乎是同时运行的,他们之间并行运行各自的run()函数,在对Counter类操作时,n的初始值都是从0开始,互不影响。
附加总结:
创建线程的方法之一是创建一个继承自QThread的类,引入#include头文件,在类的声明的开头加入Q_OBJECT宏,在类中重写run()函数,在类定义中对run()函数进行定义,即线程需要做的事情在run()函数中编写,线程类便创建完成了。线程调用时引入线程所在类的头文件,在需要线程的地方,定义线程对象,并调用start()函数启动线程,线程结束的地方可以调用stop()函数停止线程,但在之前最好加上wait()函数等待线程的结束。

terminate的说明

terminate并不会立即终止线程,它取决于系统的调度,此外调用这个函数时最好在其后调用一下wait()函数等待线程结束,但是terminate()存在危险性,因为无法知道它在何时会关闭线程,而且关闭线程时不会做清理工作,尽量少用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/524249.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C/C++ 企业发放的奖金根据利润提成。利润 (i) 低于或等于 10 万元时,奖金可提 10% ;利润高 于 10 万元,低于 20 万元时,低于 10 万元的部分按 10% 提成,高于 10 万元

目录 一.结果演示二.源代码三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 面向对象 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 设计模式 零基础 C/C 学习路线推荐 : C/C 学习目录…

第四篇:Spring Boot 整合listener

一、Spring Boot整合listener 第一种方案&#xff1a;通过注解扫描完成Listener的注册 1.1 编写一个listener WebListener public class FirstListener implements ServletContextListener {Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.pri…

2019年关于VM和Kubernetes的思考 | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;转自&#xff1a;开源云中文社区近年来&#xff0c;容器已成为云原生应用程序架构的同义词。它们重新定义了打包、分发、部署和管理应用程序的方式。但是&#xff0c;容器本身就是已有Linux技术的重新兴起&#xff0c;只不过这些技术…

Qt实现界面的窗口的局部动态添加并布局

此程序实现的是点击界面的添加界面按钮&#xff0c;新增加一个窗口&#xff0c;并实现窗口的布局&#xff0c;随着窗口个数的在布局中的增加&#xff0c;窗口大小自动缩小。创建基于QT widget Application的应用程序&#xff0c;选择基类QDialog,去掉Generate form前的勾&#…

第五篇:Spring Boot整合filter

一、Springboot整合Servlet 第一种方案&#xff1a;通过注解扫描完成filter组建的注册 1、编写自定义filter(FirstFilter) //urlPattern是一个数组可以添加多个 //WebFilter(filterName "FirstFilter",urlPatterns {"*.do","*.jsp"}) WebFilt…

C/C++ 一个整数,它加上 100 后是一个完全平方数,再加上 168 又是一个完全平方数,请问该数是多少?

目录 一.结果演示二.源代码三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 面向对象 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 设计模式 零基础 C/C 学习路线推荐 : C/C 学习目录…

QtCreate由MinGW编译的项目,换为MSVC编译器后编译无法通过

解决方法&#xff1a; 1.将文件的编码格式设置为utf-8且BOM格式&#xff1b; 2.在.pro文件中添加如下代码 msvc { QMAKE_CFLAGS /utf-8 QMAKE_CXXFLAGS /utf-8 } 其中方法一没有试过&#xff0c;我用的是方法二&#xff0c;可以编译通过。 还有一种方法&#xff1a; 在头文件…

微服务精华问答:什么是微服务架构中的DRY?| 技术头条

微服务(Microservice Architecture)是近几年流行的一种架构思想,关于它的概念很难一言以蔽之。 究竟什么是微服务呢?今天就让我们一探究竟。1Q&#xff1a;什么是微服务架构中的DRY&#xff1f;A&#xff1a;DRY代表不要重复自己。它基本上促进了重用代码的概念。这导致开发和…

第六篇:Spring Boot 访问静态资源

Spring Boot的默认静态资源的路径为&#xff1a; spring.resources.static-locationsclasspath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ 优先级从从高到低 一、Spring Boot 访问静态资源有二种方案 第一种方案&#xff08;默认&…

C/C++ 输入某年某月某日,判断这一天是这一年的第几天?

目录 一.结果演示二.源代码三.猜你喜欢 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 语言基础入门 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 面向对象 零基础 C/C 学习路线推荐 : C/C 学习目录 >> C 设计模式 零基础 C/C 学习路线推荐 : C/C 学习目录…

QT中DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x80040216 ()问题的解决

亲身经历此问题的困惑后&#xff0c;第二次遇到该问题&#xff0c;实在忍不住想把这个解决方法写下来&#xff0c;愿对和我一样遇到该问题的人有所帮助。 至于Qt产生该问题的原因&#xff0c;网上众说纷云&#xff0c;但都是一样的&#xff0c;说是缺少一个视频解码器。造成的现…

成为最大的独立开源公司,对SUSE意味着什么? | 人物志

戳蓝字“CSDN云计算”关注我们哦&#xff01;极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;作者&#xff1a;孙浩峰如果你在科技展会上看到了一只可爱的绿色小蜥蜴&#x…

第七篇:Spring Boot 整合_Thymeleaf 入门试炼 QuickStart

1.1 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency><groupId>org.springframework.boot</groupId><artifactId&…

移动场景在其缩略图中显示场景中所显示的区域

需求描述 在场景中实现拖动&#xff0c;缩放&#xff0c;并在场景的缩略图中显示其对应在视口中显示的矩形区域。 程序效果图如下&#xff1a; 开发环境&#xff1a;Qt 5.13.1 编译环境&#xff1a;MinGW64 项目结构&#xff1a; 直接上程序: main.cpp #include "dial…

Intellij Idea: Thymeleaf 命名空间th报错

在Intellij Idea下使用Thymeleaf时&#xff0c;会报th命名空间不存在的错误&#xff0c;如th:href。 <!DOCTYPE html> <html> <head><title>Hello</title><meta http-equiv"Content-Type" content"text/html; charsetUTF-8&q…

那些中国式家庭的小烦恼,我看用AI来解决就“都挺好” | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;转自&#xff1a;趣味科技v今天&#xff0c;又是《都挺好》全面承包热搜的一天。自从这…

penGL ES 2.0 和 3.0区别

目录 一.嵌入式设备的 OpenGL ES 版本二.兼容性三.着色器脚本 1.OpenGL ES shader 2.02.OpenGL ES shader 3.03.版本声明4. 默认精度修饰符 precision4.输入输出5.变量赋值 四.关于顶点缓冲区对象 VBO 与顶点数组对象 VAO五.PBO六.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : O…

setGeometry: Unable to set geometry 493x379+674+326 (frame: 517x443+662+274) on QWidgetWindow/“Dialo

qt编译的过程中出现问题&#xff1a;setGeometry: Unable to set geometry 493x379674326 (frame: 517x443662274) on QWidgetWindow/“DialogWindow” on “\.\DISPLAY1”. Resulting geometry: 555x452674326 (frame: 579x516662274) margins: 12, 52, 12, 12 minimum size: …

使用thymeleaf的时候报元素类型“meta“必须由匹配的结束标记

使用thymeleaf的时候报元素类型"meta"必须由匹配的结束标记""终止> 解决方案有二种&#xff1a; 第一种&#xff1a; 让html的标记严格严谨的语法&#xff1a; 加上结束标签第一种&#xff1a;&#xff1a;修改thymeleaf版本 <thymeleaf.version…

漫话:如何给女朋友解释什么是系统可用性? | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;转自&#xff1a;漫话编程在一个阳光明媚的周二下午&#xff0c;我正在公司里面看着即…