当前位置:网站首页>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已停止");
}
}
《让我们荡起双桨》
边栏推荐
- Awk from introduction to earth (16) discussion on the types of awk variables -- about the two types of numbers and strings
- DNA修饰贵金属纳米颗粒|DNA脱氧核糖核酸修饰金属钯Pd纳米颗粒PdNPS-DNA
- Using identity framework to realize JWT identity authentication and authorization in.Net 6.0
- 【活动报名】云原生技术交流 Meetup,8 月 6 日广州见
- EMC问题的根源在哪?
- 收藏 | 结合个人经验,我总结了这7点EMC相关知识
- Daily question - split equal sum subset
- Industry standards and certification of common electronic products
- 【青鸟学员故事】追风少年“李晓亮”
- YOLO系列损失函数详解
猜你喜欢

Don't be afraid of ESD static electricity. This article tells you some solutions

DNA modified osmium OS nanoparticles osnps DNA modified iridium nanoparticles irnps DNA
![[JVM optimization] online JVM tuning practice](/img/e3/5fa128805af0ca03f0b6715b78d398.jpg)
[JVM optimization] online JVM tuning practice

Summary of project experience

It has been rectified seven times and took half a month. Painful EMC summary

CAS vs Database optimistic lock

EMC问题的根源在哪?

Opencv's practical learning of credit card recognition (4)

MPLS --- 多协议标签交换技术

.NET 6.0中使用Identity框架实现JWT身份认证与授权
随机推荐
DNA-CuInSeQDs近红外CuInSe量子点包裹脱氧核糖核酸DNA
【活动报名】云原生技术交流 Meetup,8 月 6 日广州见
(daily question) - the longest substring without repeated characters
Adjust the array order so that odd numbers precede even numbers - two questions per day
And is two numbers of S - two questions per day
DNA修饰金属锇Os纳米颗粒OsNPS-DNA|DNA修饰金属铱纳米颗粒IrNPS-DNA
Google and Stanford jointly issued a document: why do we have to use large models?
ASP. Net core technology insider and project practice after reading
Retryer of guava
Use ffmpeg to generate single image + single audio streaming video in batches
华为高级工程师---BGP路由过滤及社团属性
DNA cuinseqds near infrared CuInSe quantum dots wrapped deoxyribonucleic acid DNA
DNA修饰贵金属纳米颗粒|DNA修饰纳米铜颗粒CuNPS-DNA|研究要点
The cornerstone of EMC - complete knowledge of electromagnetic compatibility filtering!
Summary of project experience
【jvm优化】线上JVM调优实践
[Google] solve the problem that Google browser does not pop up the account and password save box and cannot save login information
DNA deoxyribonucleic acid modified platinum nanoparticles ptnps DNA | scientific research reagent
RFID辐射测试小结
leetcode 字符串类