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_OBJECT

public:
    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_OBJECT
      void 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)
        {
            //lock
            qDebug()<<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() == 5
  sem.acquire(3);         // sem.available() == 2
  sem.acquire(2);         // sem.available() == 0
  sem.release(5);         // sem.available() == 5
  sem.release(5);         // sem.available() == 10
  sem.tryAcquire(1);      // sem.available() == 9, returns true
  sem.tryAcquire(250);    // sem.available() == 9, returns false

QMutex ://locker
 QMutex 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);

            //V
            sem->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)
        {
            //P
            sem->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_OBJECT

public:
    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 0
    for(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 发送信号

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java进阶-IO(4)

前面几篇介绍了java IO的基础部分&#xff0c;现在进入核心内容的学习&#xff0c;如File类、动态读取和序列化等&#xff0c;如下。 一、File类 1、概述 是 java.io 包中唯一代表磁盘文件本身的对象&#xff08;可以通过 File 类操作文件和目录&#xff09;&#xff0c;定义…

【Flutter 】get-cli init报错处理

报错内容 get init 命令跳出,报错内如下 Select which type of project you want to creat Synchronous waiting using dart:cli waitFor Unhandled exceotion . Dart WaitforEvent is deprecated and disabled by default. This feature will be fully removed in Dart 3.4 …

Docker安装MySQL镜像实战分享

今天我们对Docker安装MySQL镜像进行实战分享&#xff0c;以更深入的了解容器的使用场景。我们在云付服务器Ubuntu环境上已经安装好了Docker&#xff0c;接下来我们开始安装mysql5.7版本&#xff0c;安装mysql有两种思路&#xff0c;直接拉取mysql镜像和自己做mysql镜像&#xf…

【python基础学习10课_面向对象、封装、继承、多态】

一、类与对象 1、类的定义 在类的里面&#xff0c;称之为方法。 在类的外面&#xff0c;称之为函数。类&#xff1a;人类&#xff0c;一个族群&#xff0c;是一个群体类的语法规则&#xff1a;class 自定义的类名():属性 -- 变量方法 -- 函数类&#xff0c;首字母大写&#x…

软考-中级-系统集成2023年综合知识(五)

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 软考中级专栏回顾 专栏…

阿里云服务器配置选择哪个比较好?看花眼了

阿里云服务器配置怎么选择&#xff1f;CPU内存、公网带宽和系统盘怎么选择&#xff1f;个人开发者或中小企业选择轻量应用服务器、ECS经济型e实例&#xff0c;企业用户选择ECS通用算力型u1云服务器、ECS计算型c7、通用型g7云服务器&#xff0c;阿里云服务器网aliyunfuwuqi.com整…

Java常用笔试题,面试java对未来的规划

最重要的话 2021年&#xff0c;真希望行业能春暖花开。 去年由于疫情的影响&#xff0c;无数行业都受到了影响&#xff0c;互联网寒冬下&#xff0c;许多程序员被裁&#xff0c;大环境格外困难。 我被公司裁掉后&#xff0c;便着急地开始找工作&#xff0c;一次次地碰壁&#…

微信jsSDK前端签名错误,巨坑; 前后端分离的一大失误。

微信 JS 接口签名校验工具 1. 确保你后端生成的签名是正确&#xff0c;这个是第一步。否则后面都是白扯。 以用上面微信自带的验证签名工龄进行验证。 确保生成的签名和你的签名是一致的。 2. timestamp需要是字符串类型. 3. 切记&#xff0c;URL不要encode&#xff0c;如果…

9.12零钱兑换(LC518-M)(开始完全背包,与01背包的不同仅在于遍历顺序)

算法&#xff1a; 这是一道典型的背包问题&#xff0c;一看到钱币数量不限&#xff0c;就知道这是一个完全背包。 但本题和纯完全背包不一样&#xff0c;纯完全背包是凑成背包最大价值是多少&#xff0c;而本题是要求凑成总金额的物品组合个数&#xff01; 动规五步曲&#…

剑指offer--c++--n个骰子的点数

目录 题目&#xff1a; 题目分析&#xff1a; 最后编写代码&#xff1a; 输出结果 题目&#xff1a; 把n个骰子扔在地上&#xff0c;所有骰子朝上一面的点数之和为s。输入n&#xff0c;打印出s的所有可能的值出现的概率。 感谢大佬的帮助&#xff1a;https://www.cnblogs.c…

人人都写过的6个bug

大家好&#xff0c;我是知微。 程序员写bug几乎是家常便饭&#xff0c;也是我们每个人成长过程中难以避免的一部分。 为了缓解这份“尴尬”&#xff0c;今天想和大家分享一些曾经都会遇到过的bug&#xff0c;让我们一起来看看这些“经典之作”。 1、数组越界 #include <…

数据库-DDL

show databases; 查询所有数据库 select database(); 查询当前数据库 use 数据库名&#xff1b; 使用数据库 creat database[if not exists] 数据库名…

成都源聚达:开抖音店铺分数需要达到多少

在数字化浪潮中&#xff0c;抖音以其独特的平台魅力吸引了无数商家入驻。但想要开设一家抖音店铺并非随意之举&#xff0c;它需要商家达到一定的评分标准。这如同参加一场考试&#xff0c;只有成绩合格者才有资格入座。那么&#xff0c;这个分数线究竟是多少呢? 据官方数据显示…

力扣hot100:560.和为K的子数组(前缀和+哈希表)

分析&#xff1a; 这个题目乍一看&#xff0c;数据大小用暴力解法大概率会超时&#xff0c;可能想用双指针&#xff0c;但是问题出现在 可能存在负数&#xff0c;也就是说即使是找到了一个答案&#xff0c;后面也可能存在负数和正数抵消&#xff0c;又是答案&#xff0c;因此不…

【Linux】文件传输工具lrzsz的安装与使用

目录 一、关于lrzsz 二、安装lrzsz 三、lrzsz的说明及使用 1、上传命令rz 2、下载命令sz 一、关于lrzsz 在开发的过程中&#xff0c;经常遇到 需要在 Linux 和 Windows 之间上传下载文件的情况 这时&#xff0c;一般都是使用 FTP 或者 WinSCP 工具进行上传下载, 虽然也能…

用ChatGPT计算植被归一化指数NDVI并出图的详细教程

用ChatGPT结合GIS计算植被归一化指数NDVI出图教程 用ENVI计算比较繁琐&#xff0c;如今AI的盛行&#xff0c;我们可以轻松解决计算问题&#xff0c;只需1一分钟变可以出图。 详细教学请看上方视频步骤。 更多ChatGPT教学内容请见&#xff1a;ChatGPT结合GIS&#xff1a;一分钟…

深度学习_18_模型的下载与读取

在深度学习的过程中&#xff0c;需要将训练好的模型运用到我们要使用的另一个程序中&#xff0c;这就需要模型的下载与转移操作 代码&#xff1a; import math import torch from torch import nn from d2l import torch as d2l import matplotlib.pyplot as plt# 生成随机的…

服务器为什么会卡顿,出现卡顿情况怎么办

从维护服务器的角度来看&#xff0c;服务器卡顿是一种常见的问题&#xff0c;但服务器卡顿可能会影响到网站、游戏或平台的正常访问和运行&#xff0c;所以出现卡顿问题首先需要对服务器进行全面的检查&#xff0c;确定卡顿原因&#xff0c;然后选取适合的解决方案&#xff0c;…

基于Spring Boot的秒杀系统(附项目源码+论文)

摘要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。本次开发一套基于Spring Boot的秒杀系统&am…

网络编程作业day6

数据库操作的增、删、改完成 #include <myhead.h>//查询的回调函数 int callback(void* data,int count,char** argv, char** columnName) {//count是字段数//argv是字段内容//columnName是字段名称for(int i0;i<count;i) {printf("%s%s\n", columnName[…