0


QT中的线程

QT中的线程

主线程(又称 GUI线程),负责监控窗口上的任何事件,一旦发现事件,立马处理.GUI线程只负责 UI刷新.
但是有时候,任务很耗时,GUI进程会卡住,UI无响应
这个时候创建一个新的子线程,负责处理 耗时的任务,

注意:非GUI线程禁止访问 界面上任何元素. GUI线程只负责 UI刷新.
如果非要显示,子线程要传递数据给GUI,有GUI线程负责刷新.

线程的创建:
C语言: pthread_create(thread_fun) thread_fun() {while(1){ }}
Qt提供了 QThread 类, 实现了线程功能,其中有一个方法 virtual void run() ;
就是线程执行体.

子线程类myThread 继承自QThread: 实现一个QThread子类 myThread,重写run函数即可.

  1. new 子类对象
  2. start(); 线程已经执行run函数了.

互斥锁QMutex:
我们直到,线程间 可以共享内存,于是他们之间就可以通信.
但是 如果两个线程同时访问同一个资源,就会出现问题, 解决方法—加锁

睡眠函数 静态方法QThread::msleep(int msec)

我们来了解一下互斥锁

互斥锁(同步)

在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的。

在线程里也有这么一把锁——互斥锁(mutex),互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即上锁( lock )和解锁( unlock )。

【互斥锁的特点】:

  1. 原子性:把一个互斥量锁定为一个原子操作,这意味着操作系统(或pthread函数库)保证了如果一个线程锁定了一个互斥量,没有其他线程在同一时间可以成功锁定这个互斥量;
  2. 唯一性:如果一个线程锁定了一个互斥量,在它解除锁定之前,没有其他线程可以锁定这个互斥量;
  3. 非繁忙等待:如果一个线程已经锁定了一个互斥量,第二个线程又试图去锁定这个互斥量,则第二个线程将被挂起(不占用任何cpu资源),直到第一个线程解除对这个互斥量的锁定为止,第二个线程则被唤醒并继续执行,同时锁定这个互斥量。

【互斥锁的操作流程如下】:

  1. 在访问共享资源后临界区域前,对互斥锁进行加锁;
  2. 在访问完成后释放互斥锁导上的锁。在访问完成后释放互斥锁导上的锁;
  3. 对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。

下面是我们老师给的图解,非常的形象

在这里插入图片描述
在这里插入图片描述

线程的演示:

两个头文件

#ifndefTHREAD_H#defineTHREAD_H#include<QThread>#include<QMutex>structmsg{char temp;int himudity;int wind;char des[128];};

class senderThread:public QThread {
public:voidrun() override;senderThread(structmsg*p,QMutex *pMutex);senderThread(structmsg*p);~senderThread();

private:structmsg*pMsg;

    QMutex *pmutex;};

class receiverThread :public QThread {
public:receiverThread(structmsg*p,QMutex *pMutex);receiverThread(structmsg*p);~receiverThread();voidrun() override;

private:structmsg*pMsg;
    QMutex *pmutex;};#endif// THREAD_H

widget.h

#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include"thread.h"#include<QMutex>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget;}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

public slots:voidbtnClickedSlotFun();
private:
    Ui::Widget *ui;structmsg*pMsg;
    QMutex  Mutex;

    class senderThread *pSendThread;
    class receiverThread *pRecvThread;};#endif// WIDGET_H

线程文件

#include"thread.h"#include<cstdio>#include<QDebug>void senderThread::run(){staticint cnt=0;while(1){
        cnt++;

        pmutex->lock();//使用之前加锁,注意 如果发现锁已经被锁上了, 则进程睡眠等待唤醒

        pMsg->temp =(char)cnt;
        QThread::msleep(1000);
        pMsg->himudity=cnt*11;
        QThread::msleep(1000);
        pMsg->wind = cnt+100;
        QThread::msleep(1000);snprintf(pMsg->des,sizeof(pMsg->des),"sunday,tmp=%d hm=%d win=%d.",pMsg->temp,pMsg->himudity,pMsg->wind);
        pmutex->unlock();//使用之后解锁, 也会唤醒其他等待的进程}}

senderThread::senderThread(msg *p, QMutex *pMutex){
    pMsg=p;
    pmutex = pMutex;}

senderThread::senderThread(msg *p){
    pMsg=p;}

senderThread::~senderThread(){}

receiverThread::receiverThread(msg *p, QMutex *pMutex){
    pMsg=p;
    pmutex = pMutex;}

receiverThread::receiverThread(msg *p){
    pMsg=p;}

receiverThread::~receiverThread(){}void receiverThread::run(){while(1){
        pmutex->lock();qDebug()<<"tmp:"<<int(pMsg->temp)<<" hm:"<<pMsg->himudity<<" win="<<pMsg->wind<<" des:"<<pMsg->des;
        pmutex->unlock();
        QThread::sleep(1);}}

widget.cpp

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

Widget::Widget(QWidget *parent):QWidget(parent),ui(new Ui::Widget){
    ui->setupUi(this);//创建两个线程共享的空间
      pMsg = new    structmsg;memset(pMsg,0,sizeof(structmsg));
      pSendThread = new senderThread(pMsg,&Mutex);
      pRecvThread = new receiverThread(pMsg,&Mutex);
      pSendThread->start();
      pRecvThread->start();connect(ui->btntest,SIGNAL(clicked()),this,SLOT(btnClickedSlotFun()));}

Widget::~Widget(){
    delete ui;
     delete  pMsg;}void Widget::btnClickedSlotFun(){
    QString str =QString("temp=%1 hm=%2 wind=%3 des:%4").arg(int(pMsg->temp)).arg(pMsg->himudity).arg(pMsg->wind).arg(pMsg->des);
    ui->textEdit->setText(str);}

运行后我们得到的是这个效果:

在这里插入图片描述

在加锁以后我们写入的数据就不会被覆盖掉,就可以得到我们需要的数据了

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/weixin_49606782/article/details/127002395
版权归原作者 小镇春风 所有, 如有侵权,请联系我们删除。

“QT中的线程”的评论:

还没有评论