QT 语言的学习 day09 进程 和 线程

1.进程  (需要的资源多,所以不常用,)

进程的 QProcess

QProcess 是一个进程类

成员函数:

start(命令,参数); 启动进程执行可执行的程序

kill(); 结束进程

state(); 获取进程的状态

        QProcess::Running 正在运行

        QProcess::NotRuning 未运行

waitForFinished(); 等待进程结束


2.所有的代码:

ui-> 设计界面  (两个按键)

 widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QProcess>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private slots:
    void on_pushButton_start_clicked();//开始按钮的槽函数
    void on_pushButton_stop_clicked();//结束按钮的槽函数

private:
    Ui::Widget *ui;
    QProcess *pro; //定义一个进程

};

#endif // WIDGET_H

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    //进程的  QProcess
    /*QProcess 是一个进程类
    成员函数:
    start(命令,参数);  启动进程执行可执行的程序
    kill();  结束进程
    state();  获取进程的状态
        QProcess::Running  正在运行
        QProcess::NotRuning  未运行

        waitForFinished();  等待进程结束
    */
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QString>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    pro = new QProcess(this);// 进程对象的初始化   绑定父亲
}

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


//这个槽函数可以自己生成  你在  ui  设计界面设计的时候  直接点击按键  右键,转到槽  ,这个函数就自己生成了  !!
//开始进程
void Widget::on_pushButton_start_clicked()
{

    //如果进程没启动, 启动它
    if(pro->state()==QProcess::NotRunning)
    {
        qDebug()<<"启动了进程";
        //在windows上,会把路径里的斜杠,全部转为反斜杠。没说其他系统。实际上,在linux上,它并不会把反斜杠转为斜杠。所以需要我们在编码时,统一用斜杠做路径分隔符。
//        : /\    所以,一个三角形支架。按从左到右的顺序,就是斜杠和反斜杠。
        QString cmd = QString("\"C:/Program Files (x86)/Tencent/QQ/Bin/QQ.exe\"");//在字符串里面 反斜杠 \ 是转义字符   斜杠/  才是路径的
        pro->start(cmd);//这个cmd  需要双引号  这是路径
    }


}
//结束进程
void Widget::on_pushButton_stop_clicked()
{
    qDebug()<<"关闭了进程";
    //结束进程
    pro->kill();
    //等待结束
    pro->waitForFinished();
}

3. 线程

A.Qt中通过QThread直接支持多线程
1.QThread是一个跨平台的多线程解决方案
2.QThread以简洁易用的方式实现多线程编程

QThread中的关键成员函数
2.void start()--启动函数,将线程入口地址设为为run函数
3.void terminate()--强制性结束线程

多线程编程的本质有三个方面
1.并发性是多线程的本质
2.在宏观上,所有线程并行执行
3.多喝线程间相互独立,互不干涉

同步的概念--在特殊情况下,控制多线程间的相对执行顺序

代码:

main.cpp  (只用一些线程函数  和 互斥锁的使用方法)

#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QMutex>
#include <QMutexLocker>
#include <windows.h>//main函数里面使用  Sleep 

//QMutex目的是保护一次只有一个线程访问一个对象、数据结构或一段代码。QMutex通常在较为简单的代码中使用,如果代码复杂最好使用【QMutexLocker+互斥锁】进行多线程同步,
//这样可以很容易确保锁定和解锁操作执行一致。

//​ 在复杂函数和语句或异常处理代码中lock和unlock QMutex很容易出错,而且很难调试。在这种情况下,可以使用QMutexLocker替代。

//​ QMutexLocker在一个需要锁定QMutex的函数中创建。当创建QMutexLocker时,互斥锁被锁定,后面可以使用unlock()和relock()对互斥锁进行解锁和重新锁定。如果互斥锁锁定了,
//互斥对象将在QMutexLocker销毁时被解锁。

int num = 4;//两个线程的共享资源
QMutex mut;//互斥锁

class mythreadA:public QThread
{
public:
    //QThread的派生类mythreadA重写虚函数run。
    void run();//线程启动,会调用run函数。

};
class mythreadB:public QThread
{
    //QThread的派生类mythreadA重写虚函数run。
public:
    void run();

};

void mythreadA::run()
{
    QMutexLocker locker(&mut);
    //mut.lock();//上锁
    qDebug() << "mythreadA" << endl;
    while(1)
    {
        num++;
         qDebug()<<"numA = "<<num;
        sleep(1);//线程睡眠1s.

    }
    mut.unlock();//解锁
}

void mythreadB::run()
{
    //互斥锁方法二
    QMutexLocker locker(&mut);
    //mut.lock();//互斥锁的方法一
    qDebug() << "mythreadB" << endl;

    while(1)
    {
        num--;
        sleep(1);//线程睡眠1s.
        qDebug()<<"numB = "<<num;
    }

    mut.unlock();//解锁
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    mythreadA *pa = new mythreadA;//添加mythreadA对象
    mythreadB *pb = new mythreadB;//添加mythreadB对象

    pa->start();//启动线程pa,调用该对象的run函数


    //pb->start();//启动线程pb,调用该对象的run函数

    //pa->wait();//阻塞线程,直到满足其中一个条件:
    //条件1.相关联的线程已经完成执行或还没有启动
    //条件2.已经过了毫秒时间。如果time是ULONG_MAX(默认值),
    //那么等待永远不会超时(线程必须从run()返回)。如果等待超时,该函数将返回false。
   // pb->wait();


    //关闭进程
    //Sleep(10);//线程睡眠1s.
    //pa->terminate();//停止进程的运行!
    return a.exec();
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "Q:b'qt waitforfinished 怎么用'。A:waitforfinished是Qt框架中的一个函数,用于让当前线程等待另一个线程执行完毕。可以通过QProcess类中的waitforfinished函数来实现等待某个进程执行完毕后再进行后续操作。" ### 回答2: Qt提供了QProcess类来帮助我们在程序内启动外部进程并与之交互。在使用QProcess类时,我们经常会遇到需要等待其执行完成的需求。Qt为我们提供了waitforfinished()方法来实现这一需求。 使用waitforfinished()方法,我们可以在启动外部进程后等待其执行完成,然后才执行后续代码,以保证进程的执行结果被获取。waitforfinished()方法有以下几个特点: 1. 等待进程完成:在调用waitforfinished()方法时,程序会一直阻塞在该方法处,直到目标进程执行完成。 2. 返回值:waitforfinished()方法会返回进程的退出状态码。进程的退出状态码代表着进程的执行结果,通常情况下,返回0代表进程执行成功,其他数值代表不同的错误结果。 3. 可设置等待时间:waitforfinished()方法还支持设置等待时间。如果等待时间超过指定时间后,仍然没有接收到目标进程的退出信号,则会强制终止目标进程,并返回错误结果。 下面是waitforfinished()方法的典型用法: ``` QProcess process; process.start("target_program.exe"); if (!process.waitForStarted()) { // 进程启动失败 } if (!process.waitForFinished()) { // 进程执行失败 } // 获取进程退出码 int exitCode = process.exitCode(); ``` 在这段代码中,我们创建了一个QProcess对象,启动了一个名为target_program.exe的进程。接着,我们调用process.waitForStarted()方法来检查进程是否成功启动,如果启动失败,则进程不会被执行。 然后,我们在调用process.waitForFinished()方法时,程序会进入阻塞状态,直到目标进程执行完成后,才会继续执行后续代码。如果进程执行失败或等待时间超时,则会返回false,我们可以根据返回值来判断进程是否执行成功。 最后,我们通过process.exitCode()方法来获取进程的退出码,以获取进程的执行结果。 总之,waitforfinished()方法是Qt中优秀的等待进程执行完毕的方法。它的调用方式简单,返回结果准确可靠,并且支持超时功能,非常适用于需要启动外部进程并获取执行结果的情况。 ### 回答3: QT中的QProcess类提供了一种在新的进程中启动外部应用程序的方法,通过使用它的waitForFinished()函数,可以实现进程的等待,以确保进程在启动外部应用程序后完成它的任务。下面是如何使用QT waitForFinished()函数的方法: 首先,你需要创建一个QProcess对象,并把需要执行的程序作为参数传递: QProcess *process = new QProcess(this); process->start("ls", QStringList() << "-la"); 在process对象启动程序后,你可以调用waitForFinished()函数,来阻塞当前线程,直到进程执行完毕: if (!process->waitForFinished()) { qWarning() << "Process could not complete execution"; } 你也可以使用waitForReadyRead()函数来等待进程的输出数据: if (!process->waitForReadyRead()) { qWarning() << "Process output is not ready to read"; } 另外,你可以使用waitForBytesWritten()函数来等待进程向标准输入写入数据: if (!process->waitForBytesWritten()) { qWarning() << "Process did not write data to standard input"; } 总的来说,QT中的 QProcess::waitForFinished() 函数是一个很常用的函数,可以让我们实现进程的等待操作,以确保后续的操作不被执行,直到这个进程执行完毕。如果你需要使用这个函数,请先确定你已经了解了它的使用方法和注意事项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值