赞
踩
什么是线程同步?
线程同步指线程之间如何按照约定的先后次序执行。
为什么需要线程同步?
当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常
QT 线程同步方法
(一)QMutex
QMutex类就像一把锁,在互斥量之前上锁(QMutex::lock()),然后在使用完互斥量之后解锁(QMutex::unlock()),如果一个线程试图向一个已经被其它线程上锁了互斥量上锁的话,这个线程将被阻塞(挂起),直到这个互斥量被解锁。
QMutex工程中线程a,b对同一个变量g_gbalWelcome写值
mythreada.h
- #ifndef MYTHREADA_H
- #define MYTHREADA_H
-
- #include <QThread>
- #include <QMutex>//提供线程间访问序列化,比如两个线程顺序操作同一个全局变量
- #include <QDebug>
- extern QMutex g_mutex;
- extern QByteArray g_gbalWelcome;
-
- class myThreadA : public QThread
- {
- Q_OBJECT
- public:
- explicit myThreadA(QObject *parent = nullptr);
- void run();
-
- signals:
-
- };
-
- #endif // MYTHREADA_H
mythreada.cpp
- #include "mythreada.h"
-
- extern QMutex g_mutex;
- extern QByteArray g_gbalWelcome;
-
- myThreadA::myThreadA(QObject *parent)
- : QThread{parent}
- {
-
- }
-
- void myThreadA::run()
- {
- qDebug()<<"Thread A is starting"<<Qt::endl;//作用与"\n"换行类似
-
- g_mutex.lock();
- g_gbalWelcome +='W';
- sleep(2);
- g_gbalWelcome +='e';
- g_mutex.unlock();
-
- qDebug()<<"Thread A is exiting"<<Qt::endl;
-
- }
mythreadb.h
- #ifndef MYTHREADB_H
- #define MYTHREADB_H
-
- #include <QThread>
- #include <QMutex>//提供线程间访问序列化,比如两个线程顺序操作同一个全局变量
- #include <QDebug>
- extern QMutex g_mutex;
- extern QByteArray g_gbalWelcome;
-
- class MyThreadB : public QThread
- {
- Q_OBJECT
- public:
- explicit MyThreadB(QObject *parent = nullptr);
- void run();
-
- signals:
-
- };
-
- #endif // MYTHREADB_H
mythreadb.cpp
- #include "mythreadb.h"
-
- //利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数
- extern QMutex g_mutex;
- extern QByteArray g_gbalWelcome;
-
- MyThreadB::MyThreadB(QObject *parent)
- : QThread{parent}
- {
-
- }
-
- void MyThreadB::run()
- {
- qDebug()<<"Thread B is starting"<<Qt::endl;
-
- g_mutex.lock();
- g_gbalWelcome +="lcome";
- g_mutex.unlock();
-
- qDebug()<<"Thread B is exiting"<<Qt::endl;
-
- }
widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QMutex>
- #include "mythreada.h"
- #include "mythreadb.h"
- #include <QTimer>
- QT_BEGIN_NAMESPACE
- namespace Ui { class Widget; }
- QT_END_NAMESPACE
-
- extern QMutex g_mutex;
- extern QByteArray g_gbalWelcome;//其声明的函数和变量可以在本模块或其它模块中使用
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
-
- private slots:
- void on_pushButton_clicked();
- void showResult();
-
- private:
- Ui::Widget *ui;
- myThreadA *m_a;
- MyThreadB *m_b;
- QTimer *m_t;
- };
- #endif // WIDGET_H
widget.cpp
- #include "widget.h"
- #include "ui_widget.h"
-
- QMutex g_mutex;
- QByteArray g_gbalWelcome;
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
- m_a=new myThreadA(this);
- m_b=new MyThreadB(this);
- m_t=new QTimer(this);
- m_t->setSingleShot(true);
- connect(m_t,SIGNAL(timeout()),this,SLOT(showResult()));
-
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
-
- void Widget::on_pushButton_clicked()
- {
- g_gbalWelcome.clear();
-
- m_a->start();
- m_b->start();
- m_t->start(2000);//2s
- }
-
- void Widget::showResult()
- {
- qDebug()<<g_gbalWelcome<<Qt::endl;
- ui->textBrowser->setText(g_gbalWelcome);
- }
-
运行界面如图
若红框中的内容不对。可把定时器的时间延长。采用QMutex互锁写的过程,使a进程完了b进程再开始写。
(31条消息) Qt线程同步的几种方法_qt 异步线程_e5Max的博客-CSDN博客https://blog.csdn.net/e5Max/article/details/81703877
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。