当前位置:网站首页>Qt使用信号量控制线程(QSemaphore)
Qt使用信号量控制线程(QSemaphore)
2022-07-28 06:13:00 【艾米莉亚糖】
想要做的操作:通过信号量来控制多个线程的执行顺序。比如使用三个线程,按顺序来分别打印字符‘A’、‘B’、‘C’。我将使用两种创建线程的方式来实现如上操作,第一种继承QThread重新run方法,第二种通过QFeature来实现。
程序目录:

1.创建一个Widget界面,用于两种方式线程的创建

界面Widget的代码:
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "qthreadTest.h"
#include "qfeaturethread.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_feature_clicked();
void on_pushButton_thread_clicked();
private:
Ui::Widget *ui;
qThreadTest threadTest; //继承QThread重写run函数方式
qFeatureThread featureTest; //使用QFeature的方式
};
#endif // WIDGET_Hwidget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_feature_clicked()
{
featureTest.initThread();
}
void Widget::on_pushButton_thread_clicked()
{
threadTest.initThread();
}qthreadTest.h:
#ifndef QTHREADTEST_H
#define QTHREADTEST_H
#include <QObject>
#include <QThread>
#include <QMutex>
//线程1的类
class qThread1 : public QThread
{
Q_OBJECT
public:
explicit qThread1(QObject* parent = 0);
~qThread1();
void stop();
protected:
void run();
private:
volatile bool stopped = false;
};
//线程2的类
class qThread2 : public QThread
{
Q_OBJECT
public:
explicit qThread2(QObject* parent = 0);
~qThread2();
void stop();
protected:
void run();
private:
volatile bool stopped = false;
};
//线程3的类
class qThread3 : public QThread
{
Q_OBJECT
public:
explicit qThread3(QObject* parent = 0);
~qThread3();
void stop();
protected:
void run();
private:
volatile bool stopped = false;
};
class qThreadTest : public QObject
{
Q_OBJECT
public:
explicit qThreadTest(QObject *parent = 0);
~qThreadTest();
void initThread();
signals:
public slots:
private:
qThread1 thread1;
qThread2 thread2;
qThread3 thread3;
};
#endif // QTHREADTEST_HqthreadTest.cpp:
#include "qthreadTest.h"
#include <QDebug>
#include <QSemaphore>
static QSemaphore smt_used0;
static QSemaphore smt_used1;
static QSemaphore smt_used2(1);
static char ch = 'A';
qThreadTest::qThreadTest(QObject *parent) : QObject(parent)
{
}
qThreadTest::~qThreadTest()
{
if(thread1.isRunning())
thread1.stop();
if(thread2.isRunning())
thread2.stop();
if(thread3.isRunning())
thread3.stop();
}
void qThreadTest::initThread()
{
if(!thread1.isRunning())
thread1.start();
if(!thread2.isRunning())
thread2.start();
if(!thread3.isRunning())
thread3.start();
}
qThread1::qThread1(QObject *parent)
{
stopped = false;
qDebug() << QString::fromLocal8Bit("线程thread1类被构造");
}
qThread1::~qThread1()
{
stop();
qDebug() << QString::fromLocal8Bit("线程thread1被析构");
}
void qThread1::stop()
{
stopped = true;
}
void qThread1::run()
{
qDebug() << QString::fromLocal8Bit("线程thread1被开启");
while(!stopped)
{
smt_used0.acquire();
qDebug() << ch << "\n";
char cd = ++ch; //调试的时候可以看cd值
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used1.release();
}
stopped = false;
}
qThread2::qThread2(QObject *parent)
{
stopped = false;
qDebug() << QString::fromLocal8Bit("线程thread2类被构造");
}
qThread2::~qThread2()
{
stop();
qDebug() << QString::fromLocal8Bit("线程thread2被析构");
}
void qThread2::stop()
{
stopped = true;
}
void qThread2::run()
{
qDebug() << QString::fromLocal8Bit("线程thread2被开启");
while(!stopped)
{
smt_used1.acquire();
qDebug() << ch << "\n";
char cd = ++ch;
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used2.release();
}
stopped = false;
}
qThread3::qThread3(QObject *parent)
{
stopped = false;
qDebug() << QString::fromLocal8Bit("线程thread3类被构造");
}
qThread3::~qThread3()
{
stop();
qDebug() << QString::fromLocal8Bit("线程thread3被析构");
}
void qThread3::stop()
{
stopped = true;
}
void qThread3::run()
{
qDebug() << QString::fromLocal8Bit("线程thread3被开启");
while(!stopped)
{
smt_used2.acquire();
qDebug() << ch << "\n";
char cd = ++ch;
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used0.release();
}
stopped = false;
}qfeaturethread.h:
#ifndef QFEATURETHREAD_H
#define QFEATURETHREAD_H
#include <QObject>
#include <QFuture>
#include <QFutureWatcher>
#include <QtConcurrent/QtConcurrent>
class qFeatureThread : public QObject
{
Q_OBJECT
public:
explicit qFeatureThread();
~qFeatureThread();
void initThread();
private:
bool b_finish = false;
bool b_finish1 = false;
bool b_finish2 = false;
QFuture<int> future;
QFuture<int> future1;
QFuture<int> future2;
QFutureWatcher<int>* watcher = nullptr;
QFutureWatcher<int>* watcher1 = nullptr;
QFutureWatcher<int>* watcher2 = nullptr;
};
#endif // QFEATURETHREAD_Hqfeaturethread.cpp:
#include "qfeaturethread.h"
#include <QSemaphore>
#include <QDebug>
static QSemaphore smt_used0;
static QSemaphore smt_used1;
static QSemaphore smt_used2(1);
static char ch = 'A';
qFeatureThread::qFeatureThread()
{
}
qFeatureThread::~qFeatureThread()
{
if(watcher != nullptr && watcher->future().isRunning())
{
b_finish = true;
watcher->future().waitForFinished();
watcher = nullptr;
}
if(watcher1 != nullptr && watcher1->future().isRunning())
{
b_finish1 = true;
watcher1->future().waitForFinished();
watcher1 = nullptr;
}
if(watcher2 != nullptr && watcher2->future().isRunning())
{
b_finish2 = true;
watcher2->future().waitForFinished();
watcher2 = nullptr;
}
}
void qFeatureThread::initThread()
{
if(watcher == nullptr)
{
b_finish = false;
//监控线程结束的信号
watcher = new QFutureWatcher<int>;
connect(watcher, &QFutureWatcher<int>::finished,[=](){
qDebug() << QString::fromLocal8Bit("线程A已停止");
watcher->deleteLater();
});
//开启新线程
future = QtConcurrent::run([=]() mutable {
while(1)
{
smt_used0.acquire();
qDebug() << ch << "\n";
char cd = ++ch; //调试的时候可以看cd值
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used1.release();
if(b_finish)
break;
}
return 0;
});
qDebug() << QString::fromLocal8Bit("线程A已启动");
watcher->setFuture(future);
}
else if(watcher != nullptr && watcher->future().isRunning())
{
b_finish = true;
watcher->future().waitForFinished();
watcher = nullptr;
qDebug() << QString::fromLocal8Bit("线程A已停止");
}
if(watcher1 == nullptr)
{
b_finish1 = false;
//监控线程结束的信号
watcher1 = new QFutureWatcher<int>;
connect(watcher1, &QFutureWatcher<int>::finished,[=](){
qDebug() << QString::fromLocal8Bit("线程B已停止");
watcher1->deleteLater();
});
future1 = QtConcurrent::run([=]() mutable {
while(1)
{
smt_used1.acquire();
qDebug() << ch << "\n";
char cd = ++ch;
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used2.release();
if(b_finish1)
break;
}
return 0;
});
qDebug() << QString::fromLocal8Bit("线程B已启动");
watcher1->setFuture(future1);
}
else if(watcher1 != nullptr && watcher1->future().isRunning())
{
b_finish1 = true;
watcher1->future().waitForFinished();
watcher1 = nullptr;
qDebug() << QString::fromLocal8Bit("线程B已停止");
}
if(watcher2 == nullptr)
{
b_finish2 = false;
//监控线程结束的信号
watcher2 = new QFutureWatcher<int>;
connect(watcher2, &QFutureWatcher<int>::finished,[=](){
qDebug() << QString::fromLocal8Bit("线程C已停止");
watcher2->deleteLater();
});
//开启新线程
future2 = QtConcurrent::run([=]() mutable {
while(1)
{
smt_used2.acquire();
qDebug() << ch << "\n";
char cd = ++ch;
if('D' == ch)
ch = 'A';
_sleep(1000);
smt_used0.release();
if(b_finish2)
break;
}
return 0;
});
qDebug() << QString::fromLocal8Bit("线程C已启动");
watcher2->setFuture(future2);
}
else if(watcher2 != nullptr && watcher2->future().isRunning())
{
b_finish2 = true;
watcher2->future().waitForFinished();
watcher2 = nullptr;
qDebug() << QString::fromLocal8Bit("线程C已停止");
}
}
《让我们荡起双桨》
边栏推荐
- ThreadLocal things
- 细说共模干扰和差模干扰
- EMC中的基石-电磁兼容滤波知识大全!
- 4.1.4 why set the member variable to private
- [JVM optimization] online JVM tuning practice
- EMC design strategy - clock
- 【活动报名】云原生技术交流 Meetup,8 月 6 日广州见
- How to understand the adjective prefix of socket: "connection oriented" and "connectionless"
- CLion调试redis6源码
- Protobuf basic grammar summary
猜你喜欢

Industry standards and certification of common electronic products

“蔚来杯“2022牛客暑期多校训练营2补题记录(DGHJKL)

【花书笔记】 之 Chapter01 引言

Using identity framework to realize JWT identity authentication and authorization in.Net 6.0

DNA-CuInSeQDs近红外CuInSe量子点包裹脱氧核糖核酸DNA

DNA modified noble metal nanoparticles | DNA modified copper nanoparticles cunps-dna | research points

Google and Stanford jointly issued a document: why do we have to use large models?

【jvm优化超详细】常见的JVM调优场景

Near infrared two region agzs quantum dots wrapped deoxyribonucleic acid dna|dna agzsqds (Qiyue)

Forward propagation of deep learning neural networks (1)
随机推荐
Using identity framework to realize JWT identity authentication and authorization in.Net 6.0
Opencv's practical learning of credit card recognition (4)
Discrimination coverage index / index coverage / Samsung index
leetcode 字符串类
Tensorflow uses deep learning (II)
Mysql, how can we get the number of rows affected by the query?
华为交换机拆解,学EMC基本操作
EMC rectification method set
【google】解决google浏览器不弹出账号密码保存框且无法保存登录信息问题
YOLO系列损失函数详解
Elaborate on common mode interference and differential mode interference
4.1.4 why set the member variable to private
快速搭建DMHS DM之间双向同步
Forward propagation of deep learning neural networks (1)
PCB design skills of EMC
【干货】32个EMC标准电路分享!
ESD防护为何对集成电路如此重要?又该如何防护?
ThreadLocal things
磁环选型攻略及EMC整改技巧
Why is ESD protection so important for integrated circuits? How to protect?