• Qt进程和线程QProcess和QThread


    1、进程

    QProcess相当于管理进程的一个类。

    .start()相当于fork + exec函数族

    (1)头文件

    #include 
    
    • 1

    (2)声明和创建

    QProcess *np = new QProcess;
    
    • 1

    (3)启动进程

    //直接启动:
    np->start("notepad");
    //带命令行参数启动:
    QString program = "cmd.exe";
    QStringList arguments;
    arguments << "/c dir&pause";
    myProcess.start(program, arguments);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (4)如何获取进程运行时候的一些数据

    ①信号:readyRead()

    ②读取数据:readAll();

    (5)判断进程的运行状态

    //进程状态
    enum ProcessState { NotRunning, Starting, Running }
    //获取进程状态
    state()
    
    • 1
    • 2
    • 3
    • 4

    (6)关闭进程

    //直接关闭
    np->close();
    //发送杀死信号:
    np->kill();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:

    发送信号的同时,进程不一定结束,一般要用到进程的一些同步函数:
    np->waitForFinished();//阻塞到进程结束
    np->waitForStarted();//阻塞到进程开始
    np->waitForReadyRead();//阻塞到可以从当前进程读取数据
    np->waitForBytesWritten();//阻塞到数据写入进程

    (7)如果要给一个正在运行的进程发送数据

    write()

    2、线程

    源代码——可执行程序文件——进程(资源分配的基本单位 PCB)——线程(任务调度的基本单位)

    pthread_create(pid, attr, func, arg);

    QT线程有三种方式:

    1.继承QThread,重写run函数

    //自定义线程类的头文件
    //添加线程类头文件
    #include 
    //在类声明里面添加
    Q_OBJECT
     
    //重写run函数:线程任务函数
    void run();
    
    void MyThread::run()
    {
        while(1)
        {
            QThread::sleep(1);
            qDebug()<<"son run";
        }
    }
    /*----------------------------------------------------------------------------------------*/
    //在使用的地方
    //添加自定义线程类的头文件
    #include "mythread.h"
    
    //创建线程对象
    MyThread *mth;
    mth = new MyThread;
    
    //开启线程
    mth->start();
    
    //关闭线程
    mth->terminate();
    mth->wait();
     
    //线程间的数据传递
    //一般使用信号槽机制来实现
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.直接使用QThread + 自定义QObject派生类的方式

    //一个继承于QObject类的一个自定义类
    class thread_object : public QObject
        
    //自定义槽函数work()
    public slots:
        void work();
    
    void thread_object::work()
    {
        while(1)
        {
            qDebug()<<"object thread run";
            QThread::sleep(1);
        }
    
    }
    
    //在主线程中创建一个普通QThread类的对象mth
    QThread *mth;
    mth = new QThread;
    //在主线程中创建一个自定义类thread_object 的对象work
    thread_object *work;
    work = new thread_object;
    
    
    //将w的实现移入线程mth的作用范围
    work->moveToThread(mth);
    
    //用信号关联w里面想要执行的任务
    //在主线程中声明一个信号start_th();
    signals:
        void start_th();
    
    //关联这个信号的槽函数为workwork();
    connect(this, &MainWindow::start_th, work, &thread_object::work);
    
    
    //开启线程
    mth->start();
    emit start_th();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    3.用线程池 + 自定义QRunnable派生类的方式

    每一个QT程序都存在一个默认的线程池

    default_pool = QThreadPool::globalInstance();

    1.自定义一个继承于抽象类QRunnable的类(不能添加Q_OBJECT)

    class MyTask : public QRunnable
    {
    public:
        MyTask(QString name);
        void run();
        QString th_name;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.实现run函数

    void MyTask::run()
    {
        while(1)
        {
            QThread::sleep(1);
            qDebug()<<"任务:【"<th_name<<"】 正在运行...";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.创建一个线程池对象

    QThreadPool *pool;
    pool = new QThreadPool;
    
    • 1
    • 2

    4.添加任务到线程池

    //创建自定义的任务
    MyTask *t = new MyTask(ui->lineEdit->text());
    //将任务添加到线程池
    pool->start(t);
    
    • 1
    • 2
    • 3
    • 4

    5.线程池的相关函数

    int activeThreadCount() const : 当前活跃的线程数量
    
    void cancel(QRunnable *runnable):移除掉没有运行的指定任务
    
    void clear():移除掉所有没有运行的任务
    
    int expiryTimeout() const:如果有任务超时未执行,可以通过这个函数自动让其退出
    
    int maxThreadCount() const:线程池可维护的最大的线程个数
    
    void releaseThread():释放保留线程
    
    void reserveThread():保留线程
    
    void setExpiryTimeout(int expiryTimeout):与expiryTimeout()函数一起用,设置超时时间
    
    void setMaxThreadCount(int maxThreadCount):设置线程可管理的最大线程个数
    
    void start(QRunnable *runnable, int priority = 0):添加线程到线程池
    
    bool tryStart(QRunnable *runnable):尝试启动一个指定的线程
    
    bool waitForDone(int msecs = -1):等待退出
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    Anomaly-Transformer (ICLR 2022 Spotlight)复现过程及问题
    “梦幻海陆空”三军联合军事演习国防教育活动方案
    MySQL高级篇知识点——性能分析工具的使用
    FreeRTOS入门教程(事件组概念和函数使用)
    Aspose.Words for .NET查找和替换教程——在页眉和页脚中查找和替换
    iVX低代码平台系列详解 --界面功能(一)
    多目标差分进化算法(Matlab代码实现)
    文件包含漏洞利用的几种方法
    为虚拟化环境带来更强I/O性能!SR-IOV技术简介
    人工智能AI 全栈体系(八)
  • 原文地址:https://blog.csdn.net/qq_45698138/article/details/126273572