Qt进程和线程

这篇具有很好参考价值的文章主要介绍了Qt进程和线程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 进程 QProcess

1.1 知识点

在c语言中:

使用fork函数,由当前进程创建一个子进程,fork的子进程和父进程代码完全一致

在QT中:

QProcess类:额外执行的程序,执行程序后就是一个新的进程执行

QProcess:进程管理类,使用QProcess类可以操作进程

start(程序的路径):启动进程

注意

一个进程管理对象同时只能创建一个进程执行,当被管理的进程结束,可以启动下一个进程执行

1.2信号

绑定started() 信号,这个信号用来判断进程是否创建成功

绑定finished(int,QProcess::ExitStatus)信号,判断进程是否结束

绑定readyRead()信号,判断进程是否产生数据

1.3 举例

Qt进程和线程,Qt,qt,c语言,c++,算法

process

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDebug>
#include <QProcess>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    //启动是否成功的槽
    void process_started();

    //判断进程是否结束的槽
    void process_finshed();

    //判断进程是否产生数据的槽
    void process_readyRead();

private:
    Ui::MainWindow *ui;

    QProcess* process;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

//进程的使用
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //创建进程管理对象
    process = new QProcess;

    //绑定started() 信号,这个信号用来判断进程是否创建成功
    connect(process,SIGNAL(started()),this,SLOT(process_started()));

    //绑定finished(int,QProcess::ExitStatus)信号,判断进程是否结束
    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(process_finshed()));

    //绑定readyRead()信号,判断进程是否产生数据
    connect(process,SIGNAL(readyRead()),this,SLOT(process_readyRead()));

}

MainWindow::~MainWindow()
{
    delete ui;
}


//启动一个新的进程
void MainWindow::on_pushButton_clicked()
{
    //启动进程
    //start()的参数要传一个路径,比如输入“notepad”,会打开一个新的记事本出来
    //重点:一个进程管理对象只能创建一个进程,当被管理进程结束,就可以创建新的进程了
    process->start(ui->lineEdit->text());



}

//是否启动成功
void MainWindow::process_started(){
    qDebug()<<"进程启动成功";
    ui->textEdit->append("创建成功");

}

//判断进程是否结束
void MainWindow::process_finshed(){
    qDebug()<<"进程结束";

    ui->textEdit->append("进程结束");
}

//判断进程是否产生数据,当有数据产生,就读取
void MainWindow::process_readyRead(){
    //在进程产生数据时,读取该进程的数据
    QByteArray data =  process->readAll();
    ui->textEdit->append(data);
}

Qt进程和线程,Qt,qt,c语言,c++,算法

Qt进程和线程,Qt,qt,c语言,c++,算法

2. 进程间通信 QSharedMemory

2.1 知识点

核心思想就是使用  QSharedMemory:共享内存

2.2 举例

发送端

Qt进程和线程,Qt,qt,c语言,c++,算法

process_write

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSharedMemory>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    //创建共享内存对象
    QSharedMemory* shm;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //共享内存对象,并指定共内存id
    shm = new QSharedMemory("hqyj");
    //可以这样设置共内存id
//    shm->setKey();

    //创建并映射共享内存,1024是共享内存大小
    shm->create(1024);
    //单独映射也可以
//    shm->attach();

}

Widget::~Widget()
{
    delete ui;
}


//往共享内存中写
void Widget::on_pushButton_clicked()
{
    //获取共享内存首地址
    void* pdata =  shm->data();

    QString src = ui->textEdit->toPlainText();
    //src.toStdString().c_str()
    //src.toStdString()转换为c++标准字符串,c_str() 函将转换为指向以空字符(\0)结尾的 C 字符串    
    memcpy((char*)pdata,src.toStdString().c_str(),1024);
}


接收端

Qt进程和线程,Qt,qt,c语言,c++,算法

process_read

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QSharedMemory>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;

    //共享内存对象
    QSharedMemory* shm;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建共享内存对象
    shm = new QSharedMemory;

    //指定共享内存的id
    shm->setKey("hqyj");

    //映射共享内存
    shm->attach();
}

Widget::~Widget()
{
    delete ui;
}

//从共享内存中读
void Widget::on_pushButton_clicked()
{
    //将共享内存拷贝到buf
    char buf[1024];
    memcpy(buf,shm->data(),1024);

    ui->textEdit->setText(QString(buf));
}


Qt进程和线程,Qt,qt,c语言,c++,算法

3. 线程 QThread

3.1 知识点

核心思想就是,在创建一个类继承QThread,然后再新创建的类中重写run()函数执行线程,在主进程中 启动线程

线程:由进程中进行创建,在进程中额外执行一个新的任务就叫做线程。

在进程上下文切换时,系统开销比较大,多个线程在进程中,可以共享进程的资源,而调度方式和进程相同

c语言中

pthread_create(&线程id,属性对象地址,线程起始函数,线程函数的参数);

在QT中

QThread:管理线程(线程开启、线程关闭、线程执行等)

run()函数:线程的执行(当线程执行时,就是执行run函数,QThread类已经由Qt完成,run不能修改----线程任务功能固定)

通过QThread类,派生出新类,派生类 也是线程类,同时重写 run函数实现需要的线程功能,当启动线程时,就执行自己的run作为线程任务

start():启动线程

3.2 信号

Qt进程和线程,Qt,qt,c语言,c++,算法

void finished():信号,线程结束

void started():信号,线程启动

3.3 举例

thread

Qt进程和线程,Qt,qt,c语言,c++,算法

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <thread1.h>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;

    //实例化线程对象
    thread1* t1;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"


//线程的使用
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //创建线程对象
    t1 = new thread1;
    t1->str = "hello world";
}

Widget::~Widget()
{
    delete ui;
}


//启动线程
void Widget::on_pushButton_clicked()
{
    //启动
    t1->start();
}

//改变线程打印的内容
void Widget::on_pushButton_3_clicked()
{
    t1->str = ui->lineEdit->text();
}

//停止线程
void Widget::on_pushButton_2_clicked()
{
    t1->stop();
}

thread1.h

#ifndef THREAD1_H
#define THREAD1_H

#include <QThread>
#include <QDebug>

class thread1 : public QThread
{
    Q_OBJECT
public:
    thread1();

    //重写执行线程函数run()
    void run();

    void stop();


    QString str;

    bool ok;//循环标志位

};

#endif // THREAD1_H

thread1.cpp

#include "thread1.h"

thread1::thread1()
{
    ok = true;
}


//执行线程
void thread1::run(){
    while(ok){
        qDebug()<<"thread1打印:"<<str;
        sleep(1);
    }
    qDebug()<<ok;

}

//停止线程
void thread1::stop(){
    ok=false;
}

Qt进程和线程,Qt,qt,c语言,c++,算法

4. 互斥锁

防止在多线程环境下,多个线程对一个变量同时修改

QMutex:互斥量

QReadWriteLock:读写锁

4.1 举例

还是上面的程序

thread

thread1.h

Qt进程和线程,Qt,qt,c语言,c++,算法

   //互斥锁变量
    QMutex* mutex;

thread1.cpp

//执行线程
void thread1::run(){
    while(ok){
        mutex->lock();//加锁
        qDebug()<<"thread1打印:"<<str;
        mutex->unlock();//解锁
        sleep(1);
    }
    qDebug()<<ok;

}

widget.h

Qt进程和线程,Qt,qt,c语言,c++,算法

    //互斥锁变量
    QMutex* mutex;

widget.cpp

Qt进程和线程,Qt,qt,c语言,c++,算法

//改变线程打印的内容
void Widget::on_pushButton_3_clicked()
{
    mutex->lock();//加锁
    t1->str = ui->lineEdit->text();
    mutex->unlock();//解锁
}

Qt进程和线程,Qt,qt,c语言,c++,算法

4.2读写锁

Qt进程和线程,Qt,qt,c语言,c++,算法

读写锁和互斥锁差不多,思想就是

1. 如果加了读锁,别的线程也可以加读锁,但是如果要去加写锁,就必须等待读锁的释放

2. 如果加了写锁,别的线程要加锁就必须等待写锁的释放文章来源地址https://www.toymoban.com/news/detail-811060.html

到了这里,关于Qt进程和线程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • QT基础篇(12)QT5多线程

    在任何一门语言中,多线程都是一个相对其他方面比较重要的点,这里面的知识体系很庞大,同步和异步之间的处理方式,以及IO多路复用等等各种进行性能优化的方面,在往上层一点我们不可能一直进行系统层次的调用,这样太费时间也太麻烦,就到设计模式这里,比如反

    2024年01月22日
    浏览(41)
  • 操作系统进程线程(一)—进程线程协程区别、多进程多线程、进程调度算法、进程线程通信

    定义上 进程: 资源分配和拥有 的基本单位,是调度的基本单位。 运行一个可执行程序会创建一个或者多个进程;进程就是运行起来的程序 线程:程序 执行 基本单位,轻量级进程。 每个进程中都有唯一的主线程 ,主线程和进程是相互依赖的关系。 协程: 用户态 的轻量级

    2024年02月01日
    浏览(57)
  • Qt共享内存实现进程间消息队列

    在Qt 5.9中,可以使用Qt的跨进程通信机制来实现进程间的消息队列。这个机制是通过Qt的QSharedMemory、QSystemSemaphore和QSharedMemory类来实现的。 首先,你需要创建一个消息队列的服务器端和客户端。服务器端负责接收和处理消息,客户端负责发送消息。 服务器端的代码示例如下:

    2024年02月09日
    浏览(40)
  • 由Qt::BlockingQueuedConnection引起的关闭Qt主页面而后台仍有进程残留

    BUG:由Qt::BlockingQueuedConnection引起的关闭Qt主页面而后台仍有进程残留 1、错误代码示例 首先我们看下下面的代码,可以思考一下代码的错误之处 上面短短几十行代码竟会导致当我关闭Qt主页面时,后台的进程并没有完全退出。 2、原因分析 先使用转储工具获取当前后台进程的

    2024年02月08日
    浏览(43)
  • Qt6教程之三(8 )多进程、进程间通讯和调度

    本篇博客从进程的三个方面做大体介绍,欢迎读者朋友评论与交流。所写内容依然还是以适用为主,方法为辅,若需要更加深层次了解进程的朋友可先阅读操作系统原理之类的书籍。 进程在日常开发中,更多的用于不同程序之间的交互与通信,需要操作系统作为中间媒介,进

    2024年02月03日
    浏览(40)
  • C++ Qt开发:QProcess进程管理模块

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用 QProcess 组件实现针对进程的控制管理等。 当你在使用Qt进行跨平台应

    2024年03月22日
    浏览(34)
  • Qt的多线程编程

    并发 当有多个线程在操作时,如果系统 只有一个CPU ,则它根本不可能真正同时进行一个以上的线程,它只能把 CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其他线程处于挂起状态。 虽然看起来所有 线程都是一起执行

    2024年02月08日
    浏览(45)
  • QT -- 多线程 —— moveToThread

    视频教程链接: https://www.bilibili.com/video/BV1fL4y1V7QP/?spm_id_from=333.880.my_history.page.clickvd_source=b91967c499b23106586d7aa35af46413 moveToThread函数的功能:给多个任务(比如显示多个界面)各分配一个线程去执行。这样就避免了自定义好多个类继承自QThread类,从而可以避免冗余。 翻译:更改

    2024年01月25日
    浏览(36)
  • Qt中的多线程

    1 为什么需要多线程 2 Qt中使用多线程的一些注意事项 3 QThread类   3.1 QThread类的主要接口   3.2 线程的优先级 4 通过继承QThread类实现多线程 5 从QObject类进行派生实现多线程 5 小结     在现代化的程序设计开发中,多进程、多线程是经常采用的设计方式。在Qt程序中,默认线

    2024年01月17日
    浏览(69)
  • Qt多线程

    先看一个示例: 点击pushbutton后: 程序无响应啦。因为一直都在进行那个死循环。 推广一下场景:某个操作的计算量特别大,会耗时很久,如果在主线程中进行计算,页面会卡住,这时候就需要用到多线程啦。 参考: Qt中多线程写法一(步骤讲解+代码+加演示)_qt实训多线程

    2024年01月19日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包