2020-8-24 多线程操作

本文详细介绍了在Qt中实现多线程操作的方法,包括QThread的使用、线程的创建与启动,以及如何通过线程锁QMutex来解决多线程环境下对同一资源操作的问题,确保数据的安全性和一致性。

2020-8-24 多线程操作

1.多线程简述:
a.时间片轮流 每个进程轮流使用CPU
b.按照进程优先级使用CPU,如:车载,军工软件…
在这里插入图片描述
2.QThread介绍
在这里插入图片描述
在这里插入图片描述
3.流程

添加新文件-新建类在这里插入图片描述
类定义
在这里插入图片描述
添加头文件#include <QThread>

在头文件中声明宏Q_OBJECT,这样才支持信号与槽

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>



class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();
};

#endif // MYTHREAD_H

4.实现run()函数
声明:

protected:
    virtual void run();

5.代码

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QString>
#include <QDebug>

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();
    void setThreadName(QString name);
protected:
    virtual void run();
private:
    QString threadName;
};

#endif // MYTHREAD_H

main.cpp

#include <QCoreApplication>
#include "mythread.h"//加入自拟的线程类
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug()<<QThread::currentThreadId();//打印主线程ID

    MyThread thread1;//定义一个线程对象
    thread1.setThreadName("thread1");
    thread1.start();//运行线程1
    MyThread thread2;
    thread2.setThreadName("thread2");
    thread2.start();//运行线程2

    //每个线程有线程的ID

    return a.exec();
}

mythread.cpp

#include "mythread.h"

MyThread::MyThread()//构造函数
{
    //打印当前线程的ID
    qDebug()<<"MyThread()"<<threadName<<QThread::currentThreadId();
}

void MyThread::setThreadName(QString name)
{
    threadName=name;
    qDebug()<<"setThreadName()"<<threadName<<QThread::currentThreadId();
}

void MyThread::run()//run函数内的都会独立开辟线程
{
    qDebug()<<"run()"<<threadName<<QThread::currentThreadId();
    //exec();//只让线程执行一次
    while(true) //一般IO操作会使用while,如果满足条件即进入while轮询,如果不满足条件就阻塞,只运行外部线程
    {
        qDebug()<<"run()while"<<threadName<<QThread::currentThreadId();
        qDebug()<<"thread:"<<threadName;
        sleep(1);//睡眠1ms,让出权限
    }

}

6.分析在这里插入图片描述
7.线程中的connect信号与槽的连接

在这里插入图片描述
8.对同一资源操作的线程锁
QMutex(一种线程安全方式)
在这里插入图片描述
注意:线程锁QMutex必须为全局变量,不要写入类成员变量中
在这里插入图片描述
未加锁的运行结果:
在这里插入图片描述
加入全局锁之后:
代码:

mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QString>
#include <QDebug>
#include <QMutex>

class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread();
    void setThreadName(QString name);
protected:
    virtual void run();
private:
    QString threadName;
};

#endif // MYTHREAD_H
main.cpp
#include <QCoreApplication>
#include "mythread.h"//加入自拟的线程类
#include <QMutex>
QMutex globalMutex;//定义一个全局锁
int globalIndex=1;//定义一个全局变量
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);


    MyThread thread1;//定义一个线程对象
    thread1.setThreadName("thread1");
    thread1.start();//运行线程1
    MyThread thread2;
    thread2.setThreadName("thread2");
    thread2.start();//运行线程2

    //每个线程有线程的ID

    return a.exec();
}

mythread.cpp

#include "mythread.h"
extern int globalIndex;//使用全局变量
extern QMutex globalMutex;//使用全局锁
MyThread::MyThread()//构造函数
{

}

void MyThread::setThreadName(QString name)
{
    threadName=name;

}


void MyThread::run()//run函数内的都会独立开辟线程
{

    //exec();//只让线程执行一次
    while(true) //一般IO操作会使用while,如果满足条件即进入while轮询,如果不满足条件就阻塞,只运行外部线程
    {
        globalMutex.lock();//先锁住
        globalIndex++;
        //qDebug()<<"run()while"<<threadName<<QThread::currentThreadId();
        qDebug()<<"thread:"<<threadName<<"globalIndex="<<globalIndex<<&globalMutex;//&globalMutex表示da'yin打印锁对象的地址,看看是不是同一把锁
        globalMutex.unlock();//解锁对资源的操作
        sleep(1);//睡眠1ms,让出权限
    }

}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值