【QT学习】14.线程学习

本文详细介绍了线程在计算机科学中的重要性,包括其并发执行、共享内存和轻量级特性,以及如何在编程中应用线程来提高响应速度、实现并行计算和处理IO密集型任务。还提供了使用定时器和线程类实现两个实例,展示了不同方式下处理时间和随机数的场景。

一。线程了解

        线程是计算机科学中的一个重要概念,它是操作系统能够进行运算调度的最小单位。线程是进程中的一个执行流,一个进程可以包含多个线程。与进程相比,线程更轻量级,可以更高效地利用计算机资源。

线程有以下几个特点:

  1. 并发执行:多个线程可以同时执行,提高了程序的执行效率。
  2. 共享内存:同一进程中的线程共享相同的内存空间,可以方便地进行数据共享和通信。
  3. 轻量级:线程的创建和销毁开销较小,切换线程的开销也较小。

线程可以用于实现并发编程,常见的应用场景包括:

  1. 提高程序的响应速度:将耗时的操作放在一个单独的线程中执行,可以避免阻塞主线程,提高用户体验。
  2. 并行计算:将任务分解成多个子任务,每个子任务由一个线程执行,可以加速计算过程。
  3. 处理IO密集型任务:在等待IO操作完成的过程中,可以切换到其他线程执行其他任务,提高系统的利用率。

二。实例:实现显示时间的同时,显示一个随机数据

1.方式一:使用两个定时器

结果:

        点击关闭,定时器t2关闭,点击开始,定时器t2开始。

1.创建属性

2.函数实现

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //随机数
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    //t1监听
    connect(&t1,&QTimer::timeout,
            [=](){
        //获取当前时间
        QDateTime currentTime=QDateTime::currentDateTime();
        QString str=currentTime.toString("yyyy.MM.dd hh:mm:ss ddd");
        //显示当前文本
        ui->lineTime->setText(str);
    });
    //t2监听
    connect(&t2,&QTimer::timeout,[=](){
        //获得一个随机数
        QString str = QString("%1").arg(qrand()%100000000);
        //显示到行文本
        ui->lineRand->setText(str);
    });
    //定时器开始
    t1.start(1000);
    t2.start(100);
}

两个按钮的槽函数

2.线程方式二:使用两个线程(与方式三相比较)

结果:

        使用线程处理的日期,随机数如果想要做的话,需要去在创建一个线程类

1.线程类属性

线程信号isDone没有内容,就是一个信号标识符,在run函数使用emit发送信号即可。

1.wiget类的属性

注意:要创建关闭线程,因为进程关闭时,不会自动关闭线程,需要手动关闭

2.函数实现

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

    pTimeThread=new timeThread(this);
    pTimeThread->start();
    //使用线程处理时间----
    connect(pTimeThread,&timeThread::isDone,[=](){
        //获取当前时间
        QDateTime currentTime = QDateTime::currentDateTime();
        QString str = currentTime.toString("yyyy.MM.dd hh:mm:ss ddd");
        //显示到行文本
        ui->lineTime->setText(str);
    });

    //在关掉窗口的时候结束线程----
    connect(this,&Widget::destroyed,this,&Widget::quitThread);
}
//关闭线程
void Widget::quitThread(){
    //t1.stop();
    pTimeThread->quit();//结束线程  但是不会回收线程的资源
    pTimeThread->wait();//回收线程资源
}

2.线程方式三:使用两个线程

结果:

线程类属性:

    //线程处理函数
    void myTimer();
    void setFlag(bool f);
signals:
    void isDone();
private:
    bool flag;

线程类函数实现:

void mysubthread::myTimer(){
    while(flag){
        emit isDone();//发送信号 让主线程可以响应
        QThread::sleep(1);
        qDebug()<<"子进程"<<QThread::currentThread();
    }
}
void mysubthread::setFlag(bool f){
    flag=f;
}

widget类属性

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    //线程处理对象的信号
    void dealDone();//线程处理函数
    void quitThread();//关闭线程

    void on_btnOpen_clicked();
    void on_pushButton_2_clicked();

signals:
    void  startThread();
private:
    Ui::Widget *ui;
    mysubthread* pMySubThread;
    QThread* pThread;
};

widget类实现

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //创建对象
    pMySubThread=new mysubthread;
    pThread=new QThread(this);
    //添加到(自建类设置成QThread子类)
    pMySubThread->moveToThread(pThread);
    //设置线程的处理函数-》按钮信息给线程类,线程类间隔一段时间向widget发送信号
    connect(this,&Widget::startThread,pMySubThread,&mysubthread::myTimer);
    //处理线程函数 中的信号-》widget接受信号,处理数据,展示页面
    connect(pMySubThread,&mysubthread::isDone,this,&Widget::dealDone);
    //关闭窗口的时候结束线程
    connect(this,&Widget::destroyed,this,&Widget::quitThread);
}
//注意要delete-》自建类(他设置的父类是QThread,不是this,需要手动收回)
Widget::~Widget()
{
    delete pMySubThread;
    delete ui;
}
//启动线程
void Widget::on_btnOpen_clicked()
{
    pMySubThread->setFlag(true);
    pThread->start();
    emit startThread();
}
//关闭线程
void Widget::on_pushButton_2_clicked()
{
    //手动结束mysubthread::myTimer()循环
    pMySubThread->setFlag(false);

    pThread->quit();
    pThread->wait();
}
void Widget::quitThread(){
    Widget::on_pushButton_2_clicked();
}
//处理线程兑现的信号
void Widget::dealDone(){
    static int i=0;
    i++;
    ui->lcdNumber->display(i);
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值