Linux:线程同步之信号量
信号量
(1)What(什么是信号量)
提供一种计数器的方式控制对共享资源的访问;当计数器大于0时,请求资源成功并计数器-1;当计数器小于0时,线程阻塞,等待其它线程执行signal(V操作)唤醒它
(2)Why(信号量的作用)
- 实现线程的同步与互斥:通过信号量的设计,可以实现对共享资源的串行访问
- 实现线程的等待与通知机制:当信号量小于0时,当前线程将被阻塞;当信号量大于0时,会唤醒一个阻塞在信号量上的线程
(3)How(如何使用信号量实现线程同步)
step01:创建信号量
可以看作是创建一个信号量对象
sem_t sem;
step02:初始化信号量
可以看作是对信号量对象的一个初始化,这一过程会给信号量的计数器赋予一个初始值
int sem_init(sem_t *sem, int pshared, unsigned int value);
- 参数sem:被初始化的信号量对象
- 参数pshared:默认为0,表示信号量用于线程同步;其它表示信号量用于进程同步
- 参数value:表示信号量的数量,常用用于表示共享资源的数量
- 返回值:成功返回0,失败返回-1,并设置错误码
step03:请求资源
请求获取共享资源,此时信号量的计数器减1;如果信号量小于1,请求失败,线程阻塞,直到信号量满足条件时解除阻塞
int sem_wait(sem_t *sem);
- 参数sem:请求共享资源,如果sem中的计数器大于0,则请求成功,否则线程阻塞
- 返回值:成功返回0,失败返回-1,并设置错误码
step04:释放资源
释放共享资源,此时信号量的计数器加1,此时会唤醒一个等待该共享资源的线程
int sem_post(sem_t *sem);
- 参数sem:释放共享资源,sem中的计数器+1
- 返回值:成功返回0,失败返回-1,并设置错误码
step05:销毁信号量
本质就是释放信号量对象的内存空间
int sem_destroy(sem_t *sem);
- 参数sem:将要被销毁的信号量对象
- 返回值:成功返回0,失败返回-1,并设置错误码
(4)代码实例
以下代码是对共享资源的互斥访问,共享资源的个数为5
#include <semaphore.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_mutex_t mutex;
sem_t semProc;
sem_t semComu;
struct Node{int iVal;Node * ptrNext;static int iSize;
};
int Node::iSize = 0;
Node * head = NULL;
void *produce(void *arg){int i = 0;while(1){sem_wait(&semProc);pthread_mutex_lock(&mutex);int iVal = i;Node *node = new Node;node->iVal = iVal;node->ptrNext = head->ptrNext;head->ptrNext = node;Node::iSize++;cout<<"Producing "<<iVal<<"("<<Node::iSize<<")"<<endl;pthread_mutex_unlock(&mutex);sem_post(&semComu);++i;sleep(1);}
}
void *consume(void *arg){while(1){sem_wait(&semComu);pthread_mutex_lock(&mutex);if(head->ptrNext!=NULL){cout<<"Comsuing "<<head->ptrNext->iVal;Node *ptr = head->ptrNext;head->ptrNext = ptr->ptrNext;Node::iSize--;delete ptr;cout<<"("<<Node::iSize<<")"<<endl;ptr = 0;}pthread_mutex_unlock(&mutex);sem_post(&semProc);sleep(2);}return NULL;
}
int main()
{head = new Node; pthread_t tidProc, tidComu; sem_init(&semProc, 0, 5); sem_init(&semComu, 0, 0); pthread_create(&tidProc, NULL, produce, NULL); pthread_create(&tidComu, NULL, conmuse, NULL); pthread_join(tidProc, NULL); pthread_join(tidComu, NULL); return 0;
}
相关文章:
Linux:线程同步之信号量
信号量 (1)What(什么是信号量) 提供一种计数器的方式控制对共享资源的访问;当计数器大于0时,请求资源成功并计数器-1;当计数器小于0时,线程阻塞,等待其它线程执行signal(V操作&…...
GPT-SoVITS-文本转语音(你的声音不再是唯一)
本文将要介绍GPT-SoVITS的安装和使用方法 首先感谢花儿不哭大佬带来的RVC声音克隆 花儿不哭: 花儿不哭的个人空间-花儿不哭个人主页-哔哩哔哩视频 (bilibili.com) GPT-SoVITS下载地址 GitHub - RVC-Boss/GPT-SoVITS: 1 min voice data can also be used to train a …...
C语言深度剖析(部分)--剩下随缘更新
C语言深度剖析 关键字auto-最宽容大度的关键字 变量的分类 代码块:用{ }括起来的区域 局部变量:包含在代码块中的变量,局部变量具有临时性,进入代码块,自动形成局部变量,退出代码块自动释放。 全局变量…...
计算机毕业设计选题推荐-电缆行业生产管理系统-Java/Python项目实战
✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...
Linux 下查看 CPU 使用率
目录 一、什么是 CPU 使用率二、查看 CPU 利用率1、使用 top 查看2、用 pidstat 查看3、用 ps 查看4、用 htop 查看5、用 nmon 查看6、用 atop 查看7、用 glances 查看8、用 vmstat 查看9、用 sar 查看10、dstat11、iostat 三、总结 CPU 使用率是最直观和最常用的系统性能指标&…...
数理基础知识
数理基础 大数定律期望方差常见分布伯努利分布泊松分布高斯分布服从一维高斯分布的随机变量KL散度服从多元高斯分布的随机变量KL散度 Gibbs不等式凸函数Jensen不等式 似然函数泰勒近似信息论信息量信息熵KL散度JS散度交叉熵 Wiener ProcessSDE 大数定律 期望方差 x为连续随机…...
Java解决lombok和mapstruct编译模块的问题
pom.xml <dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><!-- 1.18.16版本 --><version>${lombok.version}</version><scope>provided</scope><!-- 防…...
大模型场景应用全集:持续更新中
一、应用场景 1.办公场景 智能办公:文案生成(协助构建大纲优化表达内容生成)、PPT美化(自动排版演讲备注生成PPT)、数据分析(生成公式数据处理表格生成)。 智能会议:会议策划&…...
理解RabbitMQ中的消息存储机制:非持久化、持久化与惰性队列(Lazy Queue)
文章目录 1. 非持久化消息(Transient Messages)内存压力处理 2. 持久化消息(Persistent Messages)3. 惰性队列(Lazy Queue)官方推荐 总结 在RabbitMQ中,消息的存储和处理方式可以根据不同的需求…...
【机器学习】BP神经网络正向计算
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 BP神经网络正向计算1. 引言2. BP神经网络结构回顾3. 正向计算的基本原理4. 数学…...
谷粒商城实战笔记-108~109-elasticsearch删除与批量导入
一,108-全文检索-ElasticSearch-入门-put&post修改数据 第一种更新方式: POST customer/external/1/_update {"doc":{"name": "John Doew"} }第二种更新方式: POST customer/external/1 { "name&q…...
RabbitMQ:发送者的可靠性之使用消息确认回调
文章目录 配置RabbitMQ的ConfirmCallback使用ConfirmCallback发送消息实际使用中的注意事项总结 在开发消息驱动的系统时,消息的可靠传递至关重要。而RabbitMQ作为一个广泛使用的消息队列中间件,提供了多种消息确认机制,确保消息从生产者到交…...
HCIP学习 | OSPF---LSA限制、不规则区域、附录E、选路
目录 Days06(24.8.8)OSPF---LSA限制、不规则区域、附录E、选路 特殊区域 stub 区域, 末节区域 Totally stub :完全的末节区域 NSSA区域:(not so stub area) 非完全末节区域 完全的非完全的末节区域: …...
CVE-2017-15715~Apache解析漏洞【春秋云境靶场渗透】
Apache解析漏洞 漏洞原理 # Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令。比如如下配置文件: AddType text/html .html AddLanguage zh-CN .cn# 其给 .html 后缀增加了 media-type ,值为 text/html ;给 …...
thinkphp 5.0.24生成模块
访问的形式生成模块: 1、需要在入口文件Public/index.php中加入以下代码: //生成Home模块,添加以下这句后,打开浏览器执行:http://www3.phptp5.com/public/index.php自动生成Home模块 \think\Build::module(Home); …...
值得注意!家里有带毛发动物就有浮毛?宠物空气净化器一键净化
上次跟朋友逛完街去她家,她家热情的哈基米开门就一个猛冲,我朋友接住就是一顿猛亲,亲猫一时爽,汗液粘着猫毛,粘得满手臂、满脸都是,看得鼻炎星人头皮发麻...好多养宠物的都说,梳毛根本不管用&am…...
Linux 代理(proxy)设置
有关网络代理的环境变量 环境变量说明可选的取值http_proxyhttp协议的网络连接使用该代理。ip:porthttp://ip:portsocks://ip:portsocks4://ip:portsocks5://ip:porthttps_proxyhttps协议的网络连接使用该代理。ftp_proxyftp协议使用该代理。all_proxy所有网络协议的网络连接都…...
操作系统真相还原:获取文件属性
14.15 获得文件属性 14.15.1 ls命令的幕后功臣 ls 命令中调用了大量的系统调用 stat64 和write ,其中stat64 用于获得文件的属性信息, write 用于把信息输出到屏幕,即标准输出。这里的 stat64 表示 64 位版本的 stat。 其函数原型是int sta…...
聚鼎装饰画:投资一家装饰画店铺要花费多少钱
在艺术的殿堂里,每一幅装饰画都是静默的诗篇,而开设一家装饰画店铺,便是将这份静谧与美好呈现给世界的开始。然而,背后的投资成本,却是一笔需要精打细算的账。 店铺的选址,犹如画家挑选画布,至关…...
编程的魅力、其重要性、学习方法以及未来趋势
在数字化时代,编程已不仅仅是程序员的专属技能,它逐渐渗透到我们生活的方方面面,成为连接现实与虚拟世界的桥梁。从日常使用的智能手机应用到探索宇宙奥秘的超级计算机,编程的力量无处不在。本文将深入探讨编程的魅力、其重要性、…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
