QThread+QMutex多线程编程

一个QThread代表了一个在应用程序中可以独立控制的线程,它与进程中的其他线程分享数据,但是是独立执行的,QThread从run()函数开始执行,默认run()通过exec()来开启事件循环,并在线程内运行一个Qt事件循环。要创建一个线程,需要子类化QThread,并重新实现run()函数。

问题来了,多线程并发执行的时候,共享数据的准确性是不确定的。。。

解决方法:给共享数据加一把锁。

QMutex提供了一个互斥锁(mutex),在任何时间至多有一个线程可以获得mutex,如果一个线程尝试获得mutex,而mutex此时已被锁住,则这个线程会睡眠,直到现在获得mutex的线程对mutex对其解锁为止。互斥锁常用于对共享数据的访问进行保护。

完整代码如下:


 "mythread.h"头文件
 1 #ifndef MYTHREAD_H
 2 #define MYTHREAD_H
 3 
 4 #include <QObject>
 5 #include<QThread>
 6 
 7 class myThread : public QThread
 8 {
 9 public:
10     myThread(QObject*parent=nullptr);
11     void stop();
12 protected:
13     void run() override;//需要对run()函数进行重写
14 private:
15     bool m_isStop;
16 };
17 
18 #endif // MYTHREAD_H

 

 1 #include "mythread.h"
 2 #include<QMutex>
 3 #include<QDebug>
 4 int gNum=0;
 5 QMutex mutex;
 6 myThread::myThread(QObject*parent):QThread(parent)
 7 {
 8     m_isStop=false;
 9 }
10 
11 void myThread::stop()
12 {
13     m_isStop=true;
14 }
15 
16 void myThread::run()
17 {
18     int i=0;
19     while(!m_isStop&&i++<10000){
20         mutex.lock();//处理共享数据前先加互斥锁,确保不会发生意想不到的结果(切记要加锁)
21         qDebug()<<QString::fromLocal8Bit("第%1天啦").arg(++gNum);
22         mutex.unlock();//处理完之后解锁,供其他线程使用
23     }
24 }
 1 class Widget : public QWidget
 2 {
 3     Q_OBJECT
 4 
 5 public:
 6     Widget(QWidget *parent = nullptr);
 7     ~Widget();
 8 
 9 private slots:
10     void on_startBtn_clicked();
11 
12     void on_stopBtn_clicked();
13 
14 private:
15     Ui::Widget *ui;
16     myThread m_thread1,m_thread2,m_thread3;//3个线程
17 };
 1 void Widget::on_startBtn_clicked()
 2 {
 3     m_thread1.start();//启动线程
 4     m_thread2.start();
 5     m_thread3.start();
 6 }
 7 
 8 void Widget::on_stopBtn_clicked()
 9 {
10     m_thread1.stop();
11     m_thread2.stop();
12     m_thread3.stop();
13 }

运行结果如下(姑且不考虑样式):

 

posted @ 2021-01-26 11:25  youlj  阅读(712)  评论(0编辑  收藏  举报