【QT5 多线程示例】信号量

信号量

【C++并发编程】(八)信号量

QT中的信号量类是QSemaphore,用法与C++标准中的std::counting_semaphore类似。不同的是, QSemaphore无法指定最大计数。为了限定最大计数,可以采用两个QSemaphore信号量。下面使用一个生成者-消费者例子展示QSemaphore的用法:

https://github.com/BinaryAI-1024/QtStudy/tree/master/thread/semaphore

// main.cpp
#include <QCoreApplication>
#include <QThread>
#include "producer.h"
#include "consumer.h"// 定义全局变量
const int BufferSize = 5;
QSemaphore emptySlots(BufferSize); // 管理缓冲区的空闲空间
QSemaphore fullSlots(0);           // 管理缓冲区的已用空间
int buffer[BufferSize];  int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创建线程QThread producerThread, consumerThread;// 创建生产者和消费者对象Producer producer;Consumer consumer;// 将对象移动到线程producer.moveToThread(&producerThread);consumer.moveToThread(&consumerThread);// 连接线程启动信号QObject::connect(&producerThread, &QThread::started, &producer, &Producer::produce);QObject::connect(&consumerThread, &QThread::started, &consumer, &Consumer::consume);// 启动线程producerThread.start();consumerThread.start();return a.exec();
}
// consumer.h
#ifndef CONSUMER_H
#define CONSUMER_H#include <QObject>
#include <QSemaphore>// main.cpp中的全局变量
extern QSemaphore emptySlots;
extern QSemaphore fullSlots;
extern int buffer[];
extern const int BufferSize;  // 添加 BufferSize 声明class Consumer : public QObject {Q_OBJECT
public:explicit Consumer(QObject *parent = nullptr);public slots:void consume();
};#endif // CONSUMER_H
//consumer.cpp
#include "consumer.h"
#include <QDebug>
#include <QThread>Consumer::Consumer(QObject *parent) : QObject(parent) {}void Consumer::consume() {for (int i = 0; i < 10; ++i) {fullSlots.acquire();  // 等待直到有可消费的数据,如果有fullSlots计数-1int data = buffer[i % BufferSize];  // 现在 BufferSize 可用qDebug() << "Consumed:" << data << "by thread" << QThread::currentThread();emptySlots.release(); // 释放空槽位emptySlots计数+1QThread::msleep(1000);}
}
//producer.h
#ifndef PRODUCER_H
#define PRODUCER_H#include <QObject>
#include <QSemaphore>// main.cpp中的全局变量
extern QSemaphore emptySlots;
extern QSemaphore fullSlots;
extern int buffer[];
extern const int BufferSize;class Producer : public QObject {Q_OBJECT
public:explicit Producer(QObject *parent = nullptr);public slots:void produce();
};#endif // PRODUCER_H
//producer.cpp
#include "producer.h"
#include <QDebug>
#include <QThread>Producer::Producer(QObject *parent) : QObject(parent) {}void Producer::produce() {for (int i = 0; i < 10; ++i) {emptySlots.acquire();  //  等待,直到缓冲区有空位,如果有emptySlots计数-1buffer[i % BufferSize] = i;qDebug() << "Produced:" << i << "by thread" << QThread::currentThread();fullSlots.release();   // 生产了一个数据:fullSlots计数+1QThread::msleep(500);}
}

emptySlots.acquire() 确保生产者生产的数据不会超过缓冲区大小。

fullSlots.acquire() 确保消费者不会读取空数据。

emptySlots.release()fullSlots.release() 保持生产消费的平衡。

emptySlotsfullSlots的计数有一个加一就有一个减一,保证了emptySlots计数+fullSlots计数=BuffferSize。这确保了生产者生产的数据不会超过缓冲区的大小。

结果:

Produced: 0 by thread QThread(0x77fe98)
Consumed: 0 by thread QThread(0x77fe90)
Produced: 1 by thread QThread(0x77fe98)
Produced: 2 by thread QThread(0x77fe98)
Consumed: 1 by thread QThread(0x77fe90)
Produced: 3 by thread QThread(0x77fe98)
Consumed: 2 by thread QThread(0x77fe90)
Produced: 4 by thread QThread(0x77fe98)
Produced: 5 by thread QThread(0x77fe98)
Consumed: 3 by thread QThread(0x77fe90)
Produced: 6 by thread QThread(0x77fe98)
Produced: 7 by thread QThread(0x77fe98)
Consumed: 4 by thread QThread(0x77fe90)
Produced: 8 by thread QThread(0x77fe98)
Produced: 9 by thread QThread(0x77fe98)
Consumed: 5 by thread QThread(0x77fe90)
Consumed: 6 by thread QThread(0x77fe90)
Consumed: 7 by thread QThread(0x77fe90)
Consumed: 8 by thread QThread(0x77fe90)
Consumed: 9 by thread QThread(0x77fe90)

程序中设置了消费者取走数据的速度比生产者慢,因此可以看到 buffer 被逐步填满,之后再被逐步消费的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/39954.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

各类神经网络学习:(四)RNN 循环神经网络(下集),pytorch 版的 RNN 代码编写

上一篇下一篇RNN&#xff08;中集&#xff09;待编写 代码详解 pytorch 官网主要有两个可调用的模块&#xff0c;分别是 nn.RNNCell 和 nn.RNN &#xff0c;下面会进行详细讲解。 RNN 的同步多对多、多对一、一对多等等结构都是由这两个模块实现的&#xff0c;只需要将对输入…

python每日十题(10)

在Python语言中&#xff0c;源文件的扩展名&#xff08;后缀名&#xff09;一般使用.py。 保留字&#xff0c;也称关键字&#xff0c;是指被编程语言内部定义并保留使用的标识符。Python 3.x有35个关键字&#xff0c;分别为&#xff1a;and&#xff0c;as&#xff0c;assert&am…

Harbor镜像仓库迁移与高可用集群搭建HTTPS实现实战指南

实验环境 Ubuntu22.04操作系统 registry节点 10.0.0.91 master节点 10.0.0.92 backup节点 10.0.0.93 在企业信息化建设的不同演进阶段&#xff0c;私有镜像仓库的选型策略存在显著差异。近期主导完成某企业级容器镜像仓库升级项目&#xff0c;成功实现Docker Registry至Ha…

【Python】pillow库学习笔记3-Image.mode

提取颜色通道时&#xff0c;偶然换了个图片&#xff0c;结果在在运行代码时一直报错&#xff1a; from PIL import Image im Image.open(city2.png) r,g,b im.split() om Image.merge("RGB", (b,g,r)) om.save(cBGR.jpg)Traceback (most recent call last): File…

PDF打开密码教程:让您的文档更安全

在数字化办公时代&#xff0c;PDF 文件常包含敏感信息&#xff0c;这时候&#xff0c;给PDF文件设置打开密码就成了一种有效的保护措施。这样&#xff0c;只有输入正确密码的人才能查看内容&#xff0c;大大提高了文件的安全性。如果您对这方面不清楚&#xff0c;就来看看小编分…

SOFAActs 介绍-01-白盒测试框架 overview

前言 大家好&#xff0c;我是老马。 sofastack 其实出来很久了&#xff0c;第一次应该是在 2022 年左右开始关注&#xff0c;但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFABoot-00-sofaboot 概览 SOFABoot-01-蚂蚁金服开源的 s…

Snipaste软件出现测量像素不准的问题

最近写一些前端布局的时候发现使用snipaste测量dom元素大小的时候出现和实际不符的情况。我平时写代码的时候是笔记本和一个显示屏&#xff0c;在笔记本上测量的时候发现总是和实际大小不符合&#xff0c;而在显示屏上测量的时候却并无差错&#xff0c;真是奇了怪了。 后来发现…

笔试专题(三)

文章目录 字符串中找出连续最长的数字串题解代码 拼三角题解代码 字符串中找出连续最长的数字串 题目链接 题解 1. 考察双指针 模拟 2. 算法思路&#xff1a;给定一个i 0&#xff0c;让i&#xff0c;如果遇到数字字符就创建一个变量j i&#xff0c;让j去遍历&#xff0c…

基于vue.js开发的家庭装修管理系统开发与设计(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本家庭装修管理系统采用B/S架构&#xff0c;数据库是MySQL&#xff0c;网站的搭建与开发采用了先进的Node.js语言进行编写&#xff0c;使用了VUE框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。用户的功能包括&#xff1a;注册、登录、浏览首页…

NAT网络地址转换与内网穿透

一、背景 前一篇文章提到PCDN&#xff0c; 也就是p2p技术CDN技术进行融合。 P2P技术有利于文件的快速分发。我们的CDN在控制节点分发数据的时候&#xff0c;向边缘节点传输数据&#xff0c;也是一种分发&#xff0c;还有各边缘节点强制同步数据等等&#xff0c;如果结合P2P技术…

【开源宝藏】30天学会CSS - DAY9 第九课 牛顿摆动量守恒动画

以下是一份逐步拆解教程&#xff0c;带你从零理解并复刻这个牛顿摆&#xff08;Pendulum of Newton&#xff09;动画效果&#xff0c;这是一个经典的物理演示模型&#xff0c;现在通过纯 HTML 和 CSS 实现出来&#xff0c;视觉效果炫酷、结构简洁。 &#x1f3af; 动画效果说明…

Chat2DB:一款强大的数据库管理工具,AI助力高效查询与分析

AI技术可谓是日新月异&#xff0c;其已经融入到社会的方方面面&#xff0c;今天就给大家分享一款数据库SQL客户端工具&#xff1a;Chat2DB。 1 简介 Chat2DB是一款开源的数据库管理工具&#xff0c;集成了AI 智能辅助功能&#xff0c;支持自然语言生成 SQL&#xff0c;帮助开发…

安全上网沙箱:多方面解决政企私的上网问题

在数字化的浪潮中&#xff0c;网络已成为我们工作与生活不可或缺的一部分。然而&#xff0c;网络的便捷也伴随着诸多安全隐患&#xff0c;尤其是对于企业、个人以及政企机构而言&#xff0c;安全上外网成为了至关重要的课题。 隔离保护&#xff1a;构建安全堡垒 沙箱技术在内网…

【react18】react项目使用mock模拟后台接口

前后端分离项目&#xff0c;后端还没有接口的时候&#xff0c;前端可以使用mockjs的技术实行假数据的模拟。这里使用的是mock的库msw实现这个业务. MSW msw是mock的工具&#xff0c;官网地址是在这里 使用步骤 1.安装msw npm install mswlatest --save-dev2.新建存放mock接…

2、pytest核心功能(进阶用法)

目录 1、标记&#xff08;Markers&#xff09;&#xff1a; 自定义插件 内置标记 2、夹具&#xff08;Fixtures&#xff09;&#xff1a; 夹具得用法 夹具作用域 3、钩子&#xff08;hook&#xff09;&#xff1a; 这篇是最重要的 测试文件中需要用到的 总的来说 有以下…

《TCP/IP网络编程》学习笔记 | Chapter 21:异步通知 I/O 模型

《TCP/IP网络编程》学习笔记 | Chapter 21&#xff1a;异步通知 I/O 模型 《TCP/IP网络编程》学习笔记 | Chapter 21&#xff1a;异步通知 I/O 模型同步与异步同步异步对比同步 I/O 的缺点异步 I/O 的优点 理解异步通知 I/O 模型实现异步通知 I/O 模型WSAEventSelect 函数和通知…

【2025】基于springboot+vue的医院在线问诊系统设计与实现(源码、万字文档、图文修改、调试答疑)

基于Spring Boot Vue的医院在线问诊系统设计与实现功能结构图如下&#xff1a; 课题背景 随着互联网技术的飞速发展和人们生活水平的不断提高&#xff0c;传统医疗模式面临着诸多挑战&#xff0c;如患者就医排队时间长、医疗资源分配不均、医生工作压力大等。同时&#xff0c;…

报错 standard_init_linux.go:228: exec user process caused: exec format error

docker logs 容器名 报错&#xff1a; standard_init_linux.go:228: exec user process caused: exec format error 或者 standard_init_linux.go:228: exec user process caused: input/output error 排查思路 1、检查源镜像的框架是否正确&#xff0c;是否amd64&#x…

26考研——图_图的存储(6)

408答疑 文章目录 二、图的存储图的存储相关概念邻接矩阵存储方式邻接矩阵的定义顶点的度计算邻接矩阵的特点邻接矩阵的局限性 应用场景邻接矩阵的幂次意义&#xff08;了解即可&#xff09; 邻接表存储方式邻接表定义邻接表结构邻接表的特点 邻接矩阵和邻接表的适用性差异十字…

机器学习(八)

一&#xff0c;基于协同过滤的推广算法&#xff1a; 算法原理&#xff1a; 基于用户的协同过滤(计算用户相似度→找出相似用户→根据相似用户的喜好推荐物品) 基于物品的协同过滤(计算物品相似度→找出用户喜欢的物品→推荐相似物品) 构造矩阵进行分解(将用户-物品评分矩阵分解…