lv20 QT进程线程编程
知识点:启动进程 ,线程 ,线程同步互斥
1 启动进程
应用场景:通常在qt中打开另一个程序
process模板
QString program = “/bin/ls";
QStringList arguments;
arguments << "-l" << “-a";QProcess *myProcess = new QProcess(parent);
myProcess->execute(program, arguments);
示例:
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QFileDialog>
#include <QProcess>
#include <QStringList>class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();
public slots:void showfile(){QString filename = QFileDialog::getOpenFileName();le->setText(filename);QStringList arg = {filename};QProcess ppp;ppp.execute("notepad", arg);}private:QLineEdit *le;QPushButton *pb;
};#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QVBoxLayout>Widget::Widget(QWidget *parent): QWidget(parent)
{le = new QLineEdit;pb = new QPushButton("showtxt");QVBoxLayout *vbox = new QVBoxLayout;vbox->addWidget(le);vbox->addWidget(pb);setLayout(vbox);connect(pb, SIGNAL(clicked(bool)), this, SLOT(showfile()));
}Widget::~Widget()
{}
效果在qt中使用文本编辑器打开一个文本。
2 线程
应用场景:启动一个线程和进程来辅助程序
线程:
class WorkerThread : public Qthread{
Q_OBJECTvoid run() {/* ... here is the expensive or blocking operation ... */emit resultReady(result);}
signals:void resultReady(const QString &s);};
WorkerThread x;
x.start();
-
void run()方法:这是QThread的一个虚函数,你需要在子类中重写它以实现线程的任务。当调用线程的start()方法时,这里的代码将在新的线程中执行。 -
void resultReady(const QString &s)信号:这是一个自定义信号,当线程完成工作并有结果可供返回时,将通过emit关键字发射这个信号。 -
QT是信号驱动、或者异步驱动的框架,平时app需要执行到a.exec()才会执行
双线程示例:一个线程打印数组,一个线程排序数组
thread_show.h(继承QThread类)
#ifndef THREAD_SHOW_H
#define THREAD_SHOW_H#include <Qthread>
#include <QDebug>
#include <QMutex>class thread_show : public QThread
{Q_OBJECT
public:thread_show(char *p):m_arr(p){}void run() //这是QThread的一个虚函数(qt中斜线表示),你需要在子类中重写它以实现线程的任务。当调用线程的start()方法时,这里的代码将在新的线程中执行。{while(1){//lockqDebug()<<m_arr;sleep(1);}}
private:char *m_arr;};#endif // THREAD_SHOW_H
thread_show.cpp(重写构造函数)
#include "thread_show.h"/*
thread_show::thread_show()
{}
*/
thread_rev.h
#ifndef THREAD_REV_H
#define THREAD_REV_H#include <QThread>class thread_rev : public QThread
{Q_OBJECT
public:thread_rev(char *p):m_arr(p){} //构造时,直接赋值效率高void run(){while(1){for(int i=0; i<5; i++){m_arr[i] ^= m_arr[9-i];m_arr[9-i] ^= m_arr[i];m_arr[i] ^= m_arr[9-i];}}}
private:char *m_arr;
};#endif // THREAD_REV_H
thread_rev.cpp(重写构造函数)
#include "thread_rev.h"/*
thread_rev::thread_rev()
{}
*/
main.cpp
#include "widget.h"
#include <QApplication>
#include "thread_rev.h"
#include "thread_show.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);char arr[] = "0123456789";thread_show t1(arr); //打印thread_rev t2(arr); //翻转数组t1.start();t2.start();return a.exec();
}
效果:两个线程同时操作,打印出来的数组无规律
3 线程互斥
官方示例
QSemaphore :QSemaphore sem(5); // sem.available() == 5sem.acquire(3); // sem.available() == 2sem.acquire(2); // sem.available() == 0sem.release(5); // sem.available() == 5sem.release(5); // sem.available() == 10sem.tryAcquire(1); // sem.available() == 9, returns truesem.tryAcquire(250); // sem.available() == 9, returns falseQMutex ://lockerQMutex mutex;void method1(){mutex.lock();mutex.unlock();}void method2(){mutex.lock();mutex.unlock();}
实验示例:
thread_show.h
#ifndef THREAD_SHOW_H
#define THREAD_SHOW_H#include <Qthread>
#include <QDebug>
#include <QMutex>class thread_show : public QThread
{Q_OBJECT
public:thread_show(char *p, QMutex *l):m_arr(p), m_arrlock(l){}void run() //这是QThread的一个虚函数(qt中斜线表示),你需要在子类中重写它以实现线程的任务。当调用线程的start()方法时,这里的代码将在新的线程中执行。{while(1){m_arrlock->lock();qDebug()<<m_arr;m_arrlock->unlock();sleep(1);}}
private:char *m_arr;QMutex *m_arrlock;};#endif // THREAD_SHOW_H
thread_show.cpp
#include "thread_show.h"/*
thread_show::thread_show()
{}
*/
thread_rev.h
#ifndef THREAD_REV_H
#define THREAD_REV_H#include <QThread>
#include <QMutex>class thread_rev : public QThread
{Q_OBJECT
public:thread_rev(char *p, QMutex *l):m_arr(p), m_arrlock(l){}void run(){while(1){m_arrlock->lock();for(int i=0; i<5; i++){m_arr[i] ^= m_arr[9-i];m_arr[9-i] ^= m_arr[i];m_arr[i] ^= m_arr[9-i];}m_arrlock->unlock();}}
private:char *m_arr;QMutex *m_arrlock;};#endif // THREAD_REV_H
thread_rev.cpp
#include "thread_rev.h"/*
thread_rev::thread_rev()
{}
*/
main.cpp
#include "widget.h"
#include <QApplication>
#include "thread_rev.h"
#include "thread_show.h"
#include <QMutex>int main(int argc, char *argv[])
{QApplication a(argc, argv);char arr[] = "0123456789";QMutex arr_lock;thread_show t1(arr,&arr_lock); //打印thread_rev t2(arr,&arr_lock); //翻转数组t1.start();t2.start();return a.exec();
}
效果:两个线程同时操作,打印出来的数组均为排序后的结果,排序中不会受到干扰

4 线程同步
目的:实现一个线程获取资源需要等另一个线程释放资源。
thread_hello.h
#ifndef THREAD_HELLO_H
#define THREAD_HELLO_H#include <QSemaphore>
#include <QThread>
#include <QDebug>class thread_hello : public QThread
{Q_OBJECT
public:thread_hello(QSemaphore *s):sem(s){ }void run(){while(1){qDebug()<<"hello";sleep(1);//Vsem->release();}}
private:QSemaphore *sem;
};#endif // THREAD_HELLO_H
thread_hello.cpp
#include "thread_hello.h"/*
thread_hello::thread_hello()
{}
*/
thread_world.h
#ifndef THREAD_WORLD_H
#define THREAD_WORLD_H#include <QThread>
#include <QDebug>
#include <QSemaphore>class thread_world : public QThread
{Q_OBJECT
public:thread_world(QSemaphore *s):sem(s){ }void run() //字体歪的就是虚函数{while(1){//Psem->acquire();qDebug()<<"world";}}
private:QSemaphore *sem;
};#endif // THREAD_WORLD_H
thread_world.cpp
#include "thread_hello.h"/*
thread_hello::thread_hello()
{}
*/
main.cpp
#include <QCoreApplication>
#include "thread_hello.h"
#include "thread_world.h"
#include <QSemaphore>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QSemaphore sem;thread_hello hello(&sem);thread_world world(&sem);hello.start();world.start();return a.exec();
}
效果,hello先打印,才会有world。
综合示例:实现两个进度条在下载
mythread1.h
#ifndef MYTHREAD1_H
#define MYTHREAD1_H#include <QThread>class myThread1 : public QThread
{Q_OBJECT
signals:downloaded(int);
public:myThread1();void run(){for(int i=0;i<100; i++){//p1->setValue(i);emit downloaded(i);QThread::sleep(2);}}
};#endif // MYTHREAD1_H
mythread1.cpp
#include "mythread1.h"myThread1::myThread1()
{}
mythread2.h
#ifndef MYTHREAD2_H
#define MYTHREAD2_H#include <QThread>class myThread2 : public QThread
{Q_OBJECT
signals:downloaded(int);
public:myThread2();void run(){for(int i=0;i<100; i++){//p1->setValue(i);emit downloaded(i);QThread::sleep(1);}}
};#endif // MYTHREAD2_H
mythread1.cpp
#include "mythread2.h"myThread2::myThread2()
{}
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QProgressBar>
#include "mythread2.h"
#include "mythread1.h"class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();
private:QProgressBar *p1, *p2;myThread1 *t1;myThread2 *t2;
};#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QVBoxLayout>
#include <QThread>Widget::Widget(QWidget *parent): QWidget(parent)
{p1 = new QProgressBar;p2 = new QProgressBar;QVBoxLayout *vbox = new QVBoxLayout;vbox->addWidget(p1);vbox->addWidget(p2);setLayout(vbox);t1 = new myThread1;t2 = new myThread2;connect(t1, SIGNAL(downloaded(int)), p1, SLOT(setValue(int)));connect(t2, SIGNAL(downloaded(int)), p2, SLOT(setValue(int)));t1->start();t2->start();#if 0for(int i=0;i<100; i++){p1->setValue(i);QThread::sleep(1);}for(int i=0;i<100; i++){p2->setValue(i);QThread::sleep(2);}
#endif
}Widget::~Widget()
{}

注:
downloaded(不需要实现,qt实现的不是函数)
emit发送一个信号
exit 发送信号
相关文章:
lv20 QT进程线程编程
知识点:启动进程 ,线程 ,线程同步互斥 1 启动进程 应用场景:通常在qt中打开另一个程序 process模板 QString program “/bin/ls"; QStringList arguments; arguments << "-l" << “-a";QPro…...
什么是机器人学习?
机器人学习是一种涉及人工智能和机器人技术的领域,旨在使机器人能够从经验中学习和改进其性能。通过模仿人类的学习过程,机器人可以通过不断地接收和分析信息来提高自己的技能和表现。机器人学习可以分为监督学习、无监督学习和强化学习等不同类型&#…...
裸机程序--时间片调度
1.为什么自己写一个时间片调度呢 a. 网上其实有很多成熟的时间片调度例程, 包括我最开始参加工作也是抄的网上的例程(还记得当时领导问我看明白了它的调度原理吗, 作为一个自学刚参加工作的我来说, 看懂别人的意思真的很难, 当时只能含糊其词的说看得差不多) b. 在我看来网上的…...
【web APIs】5、(学习笔记)有案例!
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、js组成window对象定时器-延迟函数location对象navigator对象histroy对象 二 、本地存储(今日重点)localStorage(重点&am…...
【刷题1】LeetCode 994. 腐烂的橘子 java题解
tag:图论 广度优先搜索 https://leetcode.cn/problems/rotting-oranges/description/?envTypestudy-plan-v2&envIdtop-100-liked 使用广度优先搜索,搜索步数就是分钟数,等到所有橘子都腐烂后,各个橘子腐烂的最长分钟数就是全部都烂的最小…...
Java的运行机制与Java开发环境的搭建
1.编译和执行 首先通过文本编辑器编写源程序(后缀为.java),再利用编译器编译成字节码文件(后缀为.class),最后利用虚拟机也叫解释器解释执行。 2.JVM、JRE和JDK的区别 简单来说, ①JVM 提供了运行 Java 程…...
【Java】面向对象之多态超级详解!!
文章目录 前言一、多态1.1 多态的概念1.2 多态的实现条件1.3 重写1.3.1方法重写的规则1.3.2重写和重载的区别 1.4 向上转型和向下转型1.4.1向上转型1.4.2向下转型 1.5 多态的优缺点1.5.1 使用多态的好处1.5.2 使用多态的缺陷 结语 前言 为了深入了解JAVA的面向对象的特性&…...
react 路由的基本原理及实现
1. react 路由原理 不同路径渲染不同的组件 有两种实现方式 ● HasRouter 利用hash实现路由切换 ● BrowserRouter 实现h5 API实现路由切换 1. 1 HasRouter 利用hash 实现路由切换 1.2 BrowserRouter 利用h5 Api实现路由的切换 1.2.1 history HTML5规范给我们提供了一个…...
[极客大挑战 2019]LoveSQL1 题目分析与详解
一、题目简介: 二、通关思路: 1、首先查看页面源代码: 我们发现可以使用工具sqlmap来拿到flag,我们先尝试手动注入。 2、 打开靶机,映入眼帘的是登录界面,首先尝试万能密码能否破解。 username: 1 or 11…...
探索RedisJSON:将JSON数据力量带入Redis世界
探索RedisJSON:将JSON数据力量带入Redis世界 当我们谈论数据存储和查询时,Redis和JSON都是无法忽视的重要角色。Redis以其高效的键值存储、快速的读/写速度、以及丰富的数据结构赢得了开发者的喜爱。而JSON,作为一种轻量级的数据交换格式&am…...
【精通Spring】基于注解管理Bean
个人名片: 🐼作者简介:一名大三在校生,喜欢AI编程🎋 🐻❄️个人主页🥇:落798. 🐼个人WeChat:hmmwx53 🕊️系列专栏:🖼️…...
Python爬虫——Urllib库-3
目录 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 获取豆瓣电影前十页的数据 ajax的post请求 总结 ajax的get请求 获取豆瓣电影第一页的数据并保存到本地 首先可以在浏览器找到发送数据的接口 那么我们的url就可以在header中找到了 再加上UA这个header 进行请…...
JAVA工程师面试专题-《消息队列》篇
1、为什么使用消息队列? 解耦、异步、削峰 2、消息队列有什么优缺点 优点:解耦、异步、削峰 缺点:系统可用性降低、系统复杂度提高、一致性问题 3、如何进⾏消息队列选型? Kafka: ○ 优点&…...
Unity3d Shader篇(十一)— 遮罩纹理
文章目录 前言一、什么是遮罩纹理?1. 遮罩纹理工作原理2. 遮罩纹理优缺点优点:缺点: 3. 遮罩纹理图 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三、效果四、总结 前言 在…...
测试开发(6)软件测试教程——自动化测试selenium(自动化测试介绍、如何实施、Selenium介绍 、Selenium相关的API)
接上次博客:测试开发(5)测试分类标准 :按测试对像划分、按是否查看代码划分、按开发阶段划分、按测试实施组织、按是否运行划分、按是否手工划分、按测试地域划分-CSDN博客 目录 什么是自动化测试 自动化测试介绍…...
【flink】Rocksdb TTL状态全量快照持续递增
flink作业中的MapState开启了TTL,并且使用rocksdb作为状态后端配置了全量快照方式(同时启用全量快照清理),希望能维持一个平稳的运行状态,但是经观察后发现效果不达预期,不仅checkpoint size持续缓慢递增&a…...
[C++] 统计程序耗时
一、简介 本文介绍了两种在C代码中统计耗时的方法,第一种使用<time.h>头文件中的clock()函数记录时间戳,统计程序耗时。第二种使用<chrono>头文件中的std::chrono::high_resolution_clock()::now()函数,后者可以方便地统计不同时…...
Redis是单线程还是多线程?
单线程为什么这么快的原因: 后来引入了多线程是因为:...
【MySQL】MySQL数据管理——DDL数据操作语言(数据表)
目录 创建数据表语法列类型字段属性SQL示例创建学生表 查看表和查看表的定义表类型设置表的类型 面试题:MyISAM和InnoDB的区别设置表的字符集删除表语法示例 修改表修改表名语法示例 添加字段语法示例 修改字段语法示例 删除字段语法示例 数据完整性实体完整性域完整…...
Qt使用QSettings类来读写ini
在Qt中,可以使用QSettings类来读写ini文件。QSettings提供了一个简单的接口,用于访问和修改ini文件中的键值对。 下面是使用QSettings类来写入ini文件的示例代码: #include <QCoreApplication> #include <QSettings>int main(i…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
