Linux——信号量

什么是信号量?

信号量是用来用于同步和互斥的。其实就是一个计数器进行PV操作,其中P操作就是让计数器–,V操作就是让计数器++。

从物理上说明信号量的P、V操作的含义。 P(S)表示申请一个资源,S.value>0表示有资源可用,其值为资源的数目;S.value=0表示无资源可用;S.value<0, 则|S.value|表示S等待队列中的进程个数。V(S)表示释放一个资源,信号量的初值应该大于等于0。P操作相当于“等待一个信号”,而V操作相当于“发送一个信号”,在实现同步过程中,V操作相当于发送一个信号说合作者已经完成了某项任务,在实现互斥过程中,V操作相当于发送一个信号说临界资源可用了。实际上,在实现互斥时,P、V操作相当于申请资源和释放资源。

信号量通常用于生产者消费者模型

进程互斥

  • 由于各进程的要求共享资源,而且有些资源互斥使用,因此各进程之间竞争使用这些资源,进程的这种关系就叫做互斥
  • 系统中某些资源一次只允许一个进程使用,称这样的进程资源为临界资源或互斥资源
  • 在进程中涉及到的互斥资源叫做临界区。

进程同步

进程同步是指在多个并发执行的进程之间协调和控制它们的执行顺序,以及管理它们对共享资源的访问,以避免竞态条件(Race Condition)和数据不一致性等并发问题。在多任务操作系统中,进程同步是一个关键的概念,确保进程能够正确地协同工作而不会产生意外的结果。

现在有这样一个场景,看电影
看电影一定要有位置(资源),只有当我们买了票,我们就拥有了这个位置(此时相当于P操作),资源会减少一个,当我们观看完电影,我们就会离开。这时位置就不属于你了(此时就是V操作)。
所以我们就有了以下的信息:
1.申请信号量的本质:让信号量计数器–
2.主要申请信号量成功,临界资源内部,一定会给你预留了你想要的资源——申请信号量的本质其实就是对临界区资源的预定机制

相关接口

信号量的初始化

在这里插入图片描述
sem:自己定义的信号量变量
pshared:0表示线程间的共享,非0表示进程间共享
value:信号量初始值(资源数)

信号量的销毁

在这里插入图片描述

信号量的等待

在这里插入图片描述
等待信号量,其实就是P操作,将计数器–

信号狼的发布

在这里插入图片描述
其实就是信号量的V操作,将计数器++

基于环形队列的生产者消费者模型

环形队列其实本质上不是一个真正的环形, 它其实本质是一个数组。
之所以是环形,是我们将它抽象了出来,更好的理解。

环形队列里面的内容就是我们要访问的临界资源,我们的生产者和消费者可能会同时访问同一个资源。
这时有两种情况:
1.资源为空,这种情况没有资源了,消费者就无法访问,就应该阻塞
2.资源为满,生产者不应该生产,阻塞
在这里插入图片描述

在这里插入图片描述

其他情况就是生产者和消费者在不同的临界资源生产和消费。

因为生产者和消费者是并发指向的,所以我们就需要保证同步和互斥。

所以,我在这里设置了2个信号量,一个代表了空间资源,一个代表了数据资源。当空间资源为满的时候,生产者就不应该生产,反之数据资源也一样。

//将sem封装了起来
class Sem
{
public:Sem(int value){//为0代表着多线程的同步,值大于0表示可以共享,用于多个相关进程的同步sem_init(&sem_,0,value);}~Sem(){sem_destroy(&sem_);}void p(){//申请信号量资源,如果申请失败,就阻塞sem_wait(&sem_);}void v(){//信号量本质就是一个计数器,这个函数就是让计数器++sem_post(&sem_);}private:sem_t sem_;
};
const int g_default_num = 5;template <class T>
class RingQueue
{
public:RingQueue(int default_num = g_default_num): ring_queue_(default_num), num_(default_num), c_step(0), p_step(0), space_sem_(default_num), data_sem_(0){pthread_mutex_init(&clock, nullptr);pthread_mutex_init(&plock, nullptr);}~RingQueue(){pthread_mutex_destroy(&clock);pthread_mutex_destroy(&plock);}//这里注意是先去进行P操作,再去加锁void push(const T &in){space_sem_.p();pthread_mutex_lock(&plock);ring_queue_[p_step++] = in;p_step %= num_;pthread_mutex_unlock(&plock);data_sem_.v();}void pop(T *out){data_sem_.p();pthread_mutex_lock(&clock);*out = ring_queue_[c_step++]; // pop数据后,生产者就多了一个资源c_step %= num_;pthread_mutex_unlock(&clock);space_sem_.v();}private:std::vector<T> ring_queue_;int num_;              // 有多少空间int c_step;            // 消费者下标int p_step;            // 生产者下标Sem space_sem_;        // 空间资源Sem data_sem_;         // 数据资源pthread_mutex_t clock; // 消费者的锁pthread_mutex_t plock; // 生产者的锁
};
void *consumer(void *args)
{RingQueue<int> *rq = (RingQueue<int> *)args;while (1){sleep(1);int x;rq->pop(&x);// 进行一定的处理 -- 不要忽略它的时间消耗问题std::cout << "消费: " << x << " [" << pthread_self() << "]" << std::endl;}
}void *productor(void *args)
{RingQueue<int> *rq = (RingQueue<int> *)args;while (1){int x = rand() % 100 + 1;rq->push(x);std::cout << "生产: " << x << " [" << pthread_self() << "]" << std::endl;}
}int main()
{srand((uint64_t)time(nullptr));RingQueue<int> *rq = new RingQueue<int>();pthread_t c[5], p[3]; // 生产者和消费者for (int i = 0; i < 5; i++){pthread_create(&c[i], nullptr, consumer, (void *)rq);}for (int i = 0; i < 3; i++){pthread_create(&p[i], nullptr, productor, (void *)rq);}for (int i = 0; i < 5; i++){pthread_join(c[i], nullptr);}for (int i = 0; i < 3; i++){pthread_join(p[i], nullptr);}return 0;
}

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

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

相关文章

OBS插件--复合模糊

复合模糊 复合是一款滤镜插件&#xff0c;支持多种模糊类型和多种蒙版效果。支持模糊源的部分显示区域&#xff0c;可以反选区域进行模糊&#xff0c;这个功能对于场景部分区域需要遮盖非常实用。 下面截图演示下操作步骤&#xff1a; 首先&#xff0c;打开 OBS直播助手 在…

【Unity 鼠标输入检测】

Unity 鼠标输入检测 Unity提供了多种方法来检测和处理鼠标输入&#xff0c;允许开发者在游戏中实现对鼠标移动、点击和滚轮滚动的响应。以下是一些基本的鼠标输入检测方法&#xff1a; 1. Input.mousePosition 这个属性返回当前鼠标指针的屏幕坐标。坐标是以像素为单位的&…

【吊打面试官系列】Java高并发篇 - 同步方法和同步块,哪个是更好的选择?

大家好&#xff0c;我是锋哥。今天分享关于 【同步方法和同步块&#xff0c;哪个是更好的选择&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 同步方法和同步块&#xff0c;哪个是更好的选择&#xff1f; 同步块是更好的选择&#xff0c;因为它不会锁住整个对象…

临近空间相关概念

临近空间概念 距地 20KM-100KM 的临近空间位于内外层空间之中&#xff0c;也称为 超高空、近空间、亚轨道等。 特点就是&#xff1a;纵跨 非电离层和电离层、空气稀薄&#xff0c;存在 臭氧、紫外、辐射等特殊环境 存在 重力波、行星波、大气放电等特殊现象。 临近空间高速飞…

##15 探索高级数据增强技术以提高模型泛化能力

文章目录 前言数据增强的重要性常见的数据增强技术高级数据增强技术在PyTorch中实现数据增强结论 前言 在深度学习领域&#xff0c;数据增强是一种有效的技术&#xff0c;它可以通过在原始数据上应用一系列变换来生成新的训练样本&#xff0c;从而增加数据的多样性&#xff0c…

前端 | 易混词卡片切换

文章目录 &#x1f4da;实现效果&#x1f4da;模块实现解析&#x1f407;html&#x1f407;css&#x1f407;javascript &#x1f4da;实现效果 绘制单词卡片效果&#xff0c;实现点击左半部分上翻&#xff0c;点击右半部分下翻。 &#x1f4da;模块实现解析 &#x1f407;…

品鉴中的个人风格:如何形成自己与众不同的红酒品鉴体验

品鉴云仓酒庄雷盛红酒不仅是一种感官体验&#xff0c;更是一种个人风格的展现。每个人都有自己与众不同的品味和偏好&#xff0c;通过品鉴红酒&#xff0c;我们可以形成自己与众不同的红酒品鉴体验。 要形成自己与众不同的红酒品鉴体验&#xff0c;首先需要勇于尝试不同类型的红…

C++语法之在谈const与模版参数

最近一直在复习C的语法&#xff0c;感觉遇到了不少问题&#xff0c;或许是之前没想的这么深。废话不说&#xff0c;开始说正事。 一、再谈const 有些朋友可能有些疑问&#xff0c;不就是const吗&#xff1f;我知道&#xff0c;const可以给非const赋值&#xff0c;反过来不行&…

通过mvn archetype 创建一个spring boot start 工程

mvn archetype https://maven.apache.org/archetype/index.html 遇到的问题 对于想自定义一个spring-boot-start的同学,比如 Springboot自定义Starter启动器 整个过程很繁琐。 定义属性开关增加 spring boot test start插件定义自动装载 spring.factories or org.springfra…

javax.net.ssl.SSLException: Received fatal alert: protocol_version已经解决

起因&#xff1a; 在帮别人讲解项目时&#xff0c;将项目的tomcat配置完&#xff0c;点击运行后&#xff0c;报错&#xff0c;信息如标题。 解决办法&#xff1a; 在csdn百度问题&#xff0c;得到的方法主要有几个&#xff1a; 1.jdk要配置在1.8以上&#xff1b; 2.数据库地…

Stable Diffusion是什么?

目录 一、Stable Diffusion是什么&#xff1f; 二、Stable Diffusion的基本原理 三、Stable Diffusion有哪些运用领域&#xff1f; 一、Stable Diffusion是什么&#xff1f; Stable Diffusion是一个先进的人工智能图像生成模型&#xff0c;它能够根据文本描述创造出高质量的图…

信息检索(36):ConTextual Masked Auto-Encoder for Dense Passage Retrieval

ConTextual Masked Auto-Encoder for Dense Passage Retrieval 标题摘要1 引言2 相关工作3 方法3.1 初步&#xff1a;屏蔽自动编码3.2 CoT-MAE&#xff1a;上下文屏蔽自动编码器3.3 密集通道检索的微调 4 实验4.1 预训练4.2 微调4.3 主要结果 5 分析5.1 与蒸馏检索器的比较5.2 …

网络运维故障排错思路!!!!!(稳了!!!)

1 网络排错的必备条件 为什么要先讲必备条件&#xff1f;因为这里所讲的网络排错并不仅仅是停留在某一个小小命令的使用上&#xff0c;而是一套系统的方法&#xff0c;如果没有这些条件&#xff0c;我真的不能保证下面讲的这些你可以听得懂&#xff0c;并且能运用到实际当中&a…

Unity值类型和引用类型

我们都知道C#编程语言中&#xff0c;数据类型被分为了两种&#xff1a; 值类型引用类型 那么什么是值类型&#xff1f;什么是引用类型呢&#xff1f;它们的区别又是什么&#xff1f; 为了搞清楚这些问题&#xff0c;我们先列举一下我们开发中会碰到的值类型和引用类型。 常…

【AI+老照片焕新】母亲节用AI把时间的印记变成暖心礼物

想念是一张泛黄的照片&#xff0c;藏在抽屉里的笑容&#xff0c;总是那么亲切。今天是母亲节&#xff0c;是不是想给妈妈来点不一样的惊喜&#xff1f;用AI技术&#xff0c;把那些老照片瞬间焕新&#xff0c;让妈妈的青春记忆重放光华&#xff01; 想象一下&#xff0c;妈妈年…

如何根据招聘信息打造完美简历

如何根据招聘信息打造完美简历 招聘信息分析简历调整策略个性化与关键词结语 在求职过程中&#xff0c;简历是第一块敲门砖。它不仅展示了你的专业技能和工作经验&#xff0c;还体现了你对所申请职位的理解和热情。然而&#xff0c;如何从招聘信息中提炼关键点&#xff0c;打造…

scrapy的入门

今天我们先学习一下scrapy的入门,Scrapy是一个快速的高层次的网页爬取和网页抓取框架&#xff0c;用于爬取网站并从页面中提取结构化的数据。 1. scrapy的概念和流程 1.1 scrapy的概念 我们先来了解一下scrapy的概念,什么是scrapy: Scrapy是一个Python编写的开源网络爬虫框架…

WebSocket前后端建立以及使用

1、什么是WebSocket WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久化的连接&#xff0c;允许服务器主动向客户端推送数据&#xff0c;同时也允许客户端向服务器发送数据&#xff0c;实现了实时的双向通信。 这部分直接说你可能听不懂&#xff1b;我…

王麻子1651商标被王麻子跨类无效宣告!

近日“王麻子1651”商标被王麻子跨类无效宣告&#xff0c;最后不予注册&#xff0c;普推知产老杨了解“王麻子”是我国著名的老字号&#xff0c;创始于1651年&#xff0c;以刀剪闻名于世&#xff0c;刀剪的商标分类主要是在8类手工器械&#xff0c;而被无效宣告的商标在16类办公…

手机电脑通用便签推荐 好用便签下载

便签软件作为一种日常记录和管理工具&#xff0c;其实用性和便捷性深受用户喜爱。一款优秀的便签软件不仅能帮助我们随时随地记录重要信息&#xff0c;还能有效提高工作效率。然而&#xff0c;市场上很多便签应用仅限于单一平台使用&#xff0c;对于需要在手机和电脑间频繁切换…