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 发送信号

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

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

相关文章

手撕Java集合之简易版Deque(LinkedList)

在目前&#xff0c;许多互联网公司的面试已经要求能手撕集合源码&#xff0c;集合源码本身算是源码里比较简单的一部分&#xff0c;但是要在面试极短的10来分钟内快速写出一个简易版的源码还是比较麻烦的&#xff0c;很容易出现各种小问题。所以在平时就要注重这方面的联系。 以…

仓储自动化新解:托盘四向穿梭车驶入智能工厂 智能仓储与产线紧密结合

目前&#xff0c;由于对仓库存储量的要求越来越高&#xff0c;拣选、输送以及出入库频率等要求也越来越高&#xff0c;对此&#xff0c;在物流仓储领域&#xff0c;自动化与智能化控制技术得以快速发展&#xff0c;货架穿梭车在自动库领域的应用越来越广泛。现阶段&#xff0c;…

linux之进程理解(1)

目录 1. 冯诺依曼体系结构 2. 操作系统(OS) 2.1 概念 2.2 设计OS的目的 2.3 定位 2.4 理解管理 3. 系统调用和库函数概念 4. 补充 1. 冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体…

chrome选项页面options page配置

options 页面用以定制Chrome浏览器扩展程序的运行参数。 通过Chrome 浏览器的“工具 ->更多工具->扩展程序”&#xff0c;打开chrome://extensions页面&#xff0c;可以看到有的Google Chrome扩展程序有“选项Options”链接&#xff0c;如下图所示。单击“选项Options”…

制作镜像与配置推送阿里云仓库

一、制作jdk镜像 1.1、Alpine linux简介 Alpine Linux是一个轻量级的Linux发行版&#xff0c;专注于安全、简洁和高效。它采用了musl libc和BusyBox&#xff0c;使得系统资源占用较少&#xff0c;启动速度较快。 Alpine Linux也提供了一个简单的包管理工具APK&#xff0c;(注…

【计算机网络_应用层】协议定制序列化反序列化

文章目录 1. TCP协议的通信流程2. 应用层协议定制3. 通过“网络计算器”的实现来实现应用层协议定制和序列化3.1 protocol3.2 序列化和反序列化3.2.1 手写序列化和反序列化3.2.2 使用Json库 3.3 数据包读取3.4 服务端设计3.5 最后的源代码和运行结果 1. TCP协议的通信流程 在之…

深入分析Android运行时环境ART:原理、特点与优化策略

摘要 随着移动互联网的快速发展&#xff0c;智能手机的性能和功能日益强大&#xff0c;其中Android操作系统因其开放性和灵活性而占据主导地位。Android运行时环境&#xff08;ART&#xff09;作为执行应用程序代码的关键组件&#xff0c;在系统性能和用户体验方面起着至关重要…

Vue+SpringBoot打造高校学生管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 学院课程模块2.3 学生选课模块2.4 成绩管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学生表3.2.2 学院课程表3.2.3 学生选课表3.2.4 学生成绩表 四、系统展示五、核心代码5.1 查询课程5.2 新…

超详细红黑树的模拟实现

前言 有人说设计出AVL树的的人是个大牛&#xff0c;那写红黑树&#xff08;RBTree&#xff09;的人就是天才&#xff01; 上一篇文章&#xff0c;我们已经学习了AVL树&#xff0c;牛牛个人认为AVL树已经够优秀了&#xff0c;那让我们一起探究一下&#xff0c;为什么红黑树比AV…

链表类型题目

文章目录 简介链表的常用技巧两数相加原理代码代码|| 两两交换链表中的节点代码原理 重排链表(重要)原理代码 合并 K 个升序链表代码递归代码 K 个一组翻转链表原理代码 简介 大家好,这里是jiantaoyab,这篇文章给大家带来的是链表相关的题目练习和解析,希望大家能相互讨论进步 …

[线代]自用大纲

部分内容整理自张宇和网络 序 题型分布&#xff1a; 题型单题分值题目数量总分值选择题5315填空题515解答题12112 *一道大题可能用到六部分所有知识 矩阵 性质 k k k倍和乘积行列式 ∣ k A ∣ k n ∣ A ∣ |kA|k^n|A| ∣kA∣kn∣A∣ ∣ A B ∣ ≠ ∣ A ∣ ∣ B ∣ |AB|≠…

如何解决微服务的数据一致性分发问题?

介绍 系统架构微服务化以后,根据微服务独立数据源的思想,每个微服务一般具有各自独立的数据源,但是不同微服务之间难免需要通过数据分发来共享一些数据,这个就是微服务的数据分发问题。Netflix/Airbnb等一线互联网公司的实践[参考附录1/2/3]表明,数据一致性分发能力,是构…

【 10X summary report】怎么看?详细解读笔记

报告内容 在开始正式的分析之前&#xff0c;需要查看在对齐和计数过程中生成的任何总结统计信息。下图是由Cell Ranger工具创建的10X总结报告&#xff0c;在从10X scRNA-seq实验生成计数矩阵时会生成。 The left half of the report describes sequencing and mapping statist…

C++之stack

1、stack简介 stack是实现的一个先进后出&#xff0c;后进先出的容器。它只有一个出口&#xff0c;只能操作最顶端元素。 2、stack库函数 &#xff08;1&#xff09;push() //向栈压入一个元素 &#xff08;2&#xff09;pop() //移除栈顶元素 &#xff08;3…

基于springboot+vue的中国陕西民俗网

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

nginx,php-fpm

一&#xff0c;Nginx是异步非阻塞多进程&#xff0c;io多路复用 1、master进程&#xff1a;管理进程 master进程主要用来管理worker进程&#xff0c;具体包括如下4个主要功能&#xff1a; &#xff08;1&#xff09;接收来自外界的信号。 &#xff08;2&#xff09;向各worker进…

SAP PP学习笔记04 - BOM2 -通过Serial来做简单的BOM变式配置,副明细,BOM状态,BOM明细状态,项目种类,递归BOM

本章继续讲BOM。 本章讲通过Serial来做简单的BOM变式配置。还讲了BOM的相关概念&#xff1a;副明细&#xff0c;BOM状态&#xff0c;BOM明细状态&#xff0c;项目种类&#xff0c;递归BOM 等。 1&#xff0c;通过Serial&#xff08;序列号&#xff09;来做简单的 VC&#xff0…

Some collections -- 2024.3

一、TensorFlow Android (dataset: Mnist) We used TensorFlow to define and train our machine learning model, which can recognize handwritten numbers, called a number classifier model in machine learning terminology. We transform the trained TensorFlow mod…

2024.03.01作业

1. 基于UDP的TFTP文件传输 #include "test.h"#define SER_IP "192.168.1.104" #define SER_PORT 69 #define IP "192.168.191.128" #define PORT 9999enum mode {TFTP_READ 1,TFTP_WRITE 2,TFTP_DATA 3,TFTP_ACK 4,TFTP_ERR 5 };void get_…

高维中介数据:基于交替方向乘子法(ADMM)的高维度单模态中介模型的参数估计(入门+实操)

全文摘要 用于高维度单模态中介模型的参数估计&#xff0c;采用交替方向乘子法&#xff08;ADMM&#xff09;进行计算。该包提供了确切独立筛选&#xff08;SIS&#xff09;功能来提高中介效应的敏感性和特异性&#xff0c;并支持Lasso、弹性网络、路径Lasso和网络约束惩罚等不…