一。线程了解
线程是计算机科学中的一个重要概念,它是操作系统能够进行运算调度的最小单位。线程是进程中的一个执行流,一个进程可以包含多个线程。与进程相比,线程更轻量级,可以更高效地利用计算机资源。
线程有以下几个特点:
- 并发执行:多个线程可以同时执行,提高了程序的执行效率。
- 共享内存:同一进程中的线程共享相同的内存空间,可以方便地进行数据共享和通信。
- 轻量级:线程的创建和销毁开销较小,切换线程的开销也较小。
线程可以用于实现并发编程,常见的应用场景包括:
- 提高程序的响应速度:将耗时的操作放在一个单独的线程中执行,可以避免阻塞主线程,提高用户体验。
- 并行计算:将任务分解成多个子任务,每个子任务由一个线程执行,可以加速计算过程。
- 处理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); }