当前位置:网站首页>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已停止");
}
}
《让我们荡起双桨》
边栏推荐
- 【干货】32个EMC标准电路分享!
- GD32使用ST的HAL库和GD官方库的一些体会
- 【活动报名】云原生技术交流 Meetup,8 月 6 日广州见
- Flowable workflow all business concepts
- 非关系型数据库之Redis【redis安装】
- ArcGIS JS自定义Accessor,并通过watchUtils相关方法watch属性
- 磁环选型攻略及EMC整改技巧
- Why is ESD protection so important for integrated circuits? How to protect?
- 我们如何在mysql中运行批处理模式?
- Advanced pointer practice
猜你喜欢

EMC's "don't come back until you rectify"

Introduction to magnetic ring selection and EMC rectification skills

Flowable workflow all business concepts

Dry goods | share an EMC actual case and rectification process

YOLO系列损失函数详解

ASP. Net core technology insider and project practice after reading

2022年湖南工学院ACM集训第五次周测AD题题解

Protobuf basic grammar summary

.NET 6.0中使用Identity框架实现JWT身份认证与授权

xmpp 服务研究(二) prosody 创建账户
随机推荐
node(一)
华为高级工程师---BGP路由过滤及社团属性
@Documented 的作用
Method of hiding scroll bar in wechat applet
GD32使用ST的HAL库和GD官方库的一些体会
ThreadLocal things
And is two numbers of S - two questions per day
[solution] visual full link log tracking - log tracking system
Mysql, how can we get the number of rows affected by the query?
win系统添加打印机
RFID辐射测试小结
Dry goods | share an EMC actual case and rectification process
MySQL基础知识学习(二)
整改了七次,花了半个月时间,惨痛的EMC总结
Use ffmpeg to generate single image + single audio streaming video in batches
DNA modified noble metal nanoparticles | DNA modified copper nanoparticles cunps-dna | research points
How to analyze the taxi business problem of didi SQL interview question
Daily question - split equal sum subset
JUC原子类: CAS, Unsafe、CAS缺点、ABA问题如何解决详解
【干货】32个EMC标准电路分享!