12.进程同步与信号量

【README】

1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;

2.进程同步: 让进程间的合作变得合理有序;

3.通过 信号量 来实现进程同步 ;

4.操作系统借助信号量实现进程合作,进程走走停停;(进程什么时候停,在哪个地方停特别重要)


【1】进程合作:多进程共同完成一个任务

 【例1】司机与售票员例子

司机

售票员

While(true) {

  启动车辆;// 等待信号1

  正常运行;

  到站停车;// 发送信号2

}

While(true) {

   关门;// 发送信号1

  售票;

  开门; // 等待信号2

}

【例2】生产者消费者

生产者

消费者

阻塞直到 counter 不等于 BUFFER_SIZE;

生产数据后,counter加1,类似向消费者发送信号;

阻塞直到counter不等于0;

消费数据后,counter减1,类似向生产者发送信号;


 【2】进程同步

进程同步定义: 需要让进程走走停停,保证多进程合作的合理有序;


 【3】信号量语义

1)只发信号还不能解决全部问题;

  • 信号只能表示 有 或者 没有;引入信号量表达更丰富的信息;

2)问题描述:

  • 当 counter 等于 BUFFER_SIZE 时,生产者1睡眠;
  • 当 counter 等于 BUFFER_SIZE 时,生产者2睡眠;
  • 接着,消费者消费一条数据,counter减1;
  • 此时 counter减1后等于 BUFFER_SIZE    减1,所以消费者会调用 wakeup唤醒生产者1;
  • 接着, 消费者循环消费另外1条数据,counter减1;

出现的问题

  • 此时counter减1后等于 BUFFER_SIZE 减2 (因为这是第2次消费),因为不满足 counter==BUFFER_SIZE-1 条件,所以消费者不会唤醒生产者2;
  • 显然,counter语义 不足以唤醒所有生产者,所以引入了信号量;
  • (counter记录的是空闲缓冲区数量,而无法记录睡眠的生产者数量,所以根据counter语义无法唤醒所有睡眠的生产者)

3)信号量
信号量不仅需要记录睡眠和唤醒,还需要记录当前阻塞的生产者个数等其他信息;

 4)信号量开始工作

步骤

生产者与消费者执行详情

信号量

sem值

1

缓冲区满,生产者P1执行, P1睡眠,信号量减1;则信号量为-1;(信号量-1表示1个生产者睡眠)

-1

2

生产者P2执行, P2睡眠,信号量减1;则信号量为-2(表示2个生产者睡眠)

-2

3

消费者执行1次循环, wakeup唤醒P1后,信号量加1得到-1;(表示1个生产者睡眠)

-1

4

消费者再执行1次循环, wakeup唤醒P2,信号量加1得到0;(没有生产者睡眠)

0

5

消费者在执行一次循环;信号量加1;(表示有1个可用缓冲空间)

1

6

生产者P3执行,信号量减1;

0

信号量sem值含义:

  • -2: 有2个生产者阻塞,或者欠生产者队列2个单位缓冲空间;
  • -1: 有1个生产者阻塞,或者欠生产者队列1个单位缓冲空间;
  • 0: 没有生产者阻塞,正常运行;
  • 1: 表示还有1个单位的可用缓冲空间;
  • 2:表示还有2个单位的可用缓冲空间;

【小结】

  • 接下来,生产者与消费者就可以根据  信号量sem  来决定进程同步,或决定多个进程合作的合理有序执行;


5)基于信号量的进程合作
多个进程合作完成一件事,多个进程在执行过程中,执行的推进顺序要合理有序;
具体地,在执行一定程度后,进程根据信号量判断是否停下来等待;

  • 5.1)生产者:若信号量等于0或负值,则生产者进程等待,且信号量减1;
  • 5.2)消费者:若信号量等于负值,则消费者唤醒一个生产者进程,且信号量加1;
  • 若信号量等于0,则消费者正常执行,且信号量加1;

【4】信号量实现

1)信号量定义:一种特殊整型变量,量用来记录,信号用来判断是否睡眠sleep和唤醒wakeup;
2)信号量代码

// 信号量代码
struct semaphore() 
{// 记录资源个数int value ; // 进程阻塞队列(记录在该信号量上等待的进程) PCB *queue;  
}// 生产者:消费资源(这里消费资源指的是生产者消费一个空闲缓冲区,或一个数组项)
P (semaphore s) 
{s.value--; // 消费资源 if (s.value < 0) {sleep(s.queue);  // 当前生产者进程睡眠 }
}// 消费者:产生资源 (这里产生资源指的是消费者释放一个空闲缓存区,或一个数组项)
V (semaphore s)
{s.value++; // 释放资源if (s.value <=0 ) {wakeup(s.queue);  // 消费者唤醒睡眠的生产者进程 }
}

 【补充】 荷兰语中

  • P表示proberen,即test测试的意思,即生产者;
  • V 表示 verhogen,即increment,增加资源的意思,即消费者;

【5】用信号量解决生产者消费者问题

 1)信号量解决生产者消费者问题的源代码

  • 下面源代码有3个信号量
    • full:缓存区中数据或内容个数,或已占用的缓冲区个数;
    • empty:空闲缓冲区个数;
    • mutex:互斥信号量,同时只允许1个进程进入代码;
// 1 用文件定义共享缓冲区 
int fd = open("buffer.txt");
write(fd, 0, sizeof(in)); // 写入数据到in位置 
read(fd, 0, sizeof(out)); // 从out位置读取数据 // 2 信号量的定义和初始化 
semaphore full = 0; // 表示缓冲区中已生产的数据(内容)个数,或已用缓冲区个数; 
semaphore empty = BUFFER_SIZE; // 表示空闲缓冲区个数 
semaphore mutex = 1; // 互斥信号量,同时只能有1个进程进去;// 3 生产者 
Producer(item) {P(empty); // 生产者先测试empty信号量是否为0(为0表示没有空闲缓冲区)P(mutex); // 读取in,把item写入到in的位置上 (生产操作)V(mutex); V(full); // 增加数据(内容)个数 
}// 4 消费者 
Consumer() {P(full);  // 消费者先测试缓冲区是否存在内容,则没有则阻塞P(mutex); // 判断是否可以访问文件,mutex是互斥信号量,同时只有1个进程可以访问文件(mutex减1, 获取mutex信号量或锁)// 读取out,从文件中的out位置读出到item,打印item (消费操作)V(mutex); // mutex加1,释放mutex 信号量V(empty);// 消费者在消费完后,增加空闲缓冲区个数 
}

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

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

相关文章

如何使 WebAPI 自动生成漂亮又实用在线API文档

1.前言 1.1 SwaggerUI SwaggerUI 是一个简单的Restful API 测试和文档工具。简单、漂亮、易用&#xff08;官方demo&#xff09;。通过读取JSON 配置显示API. 项目本身仅仅也只依赖一些 html,css.js静态文件. 你可以几乎放在任何Web容器上使用。 1.2 Swashbuckle Swashbuckle 是…

springboot超详细教程_SpringBoot五步配置Mybatis超简教程

第一步&#xff1a;Maven里面添加mybatis的引用jar包&#xff1a;org.mybatis.spring.bootmybatis-spring-boot-starter1.3.1com.github.pagehelperpagehelper-spring-boot-starter1.2.3mysqlmysql-connector-javaorg.springframeworkspring-tx第二步&#xff1a;在application…

13.信号量临界区保护

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.操作系统使用信号量实现进程同步&#xff08;合作&#xff09;&#xff0c;走走停停&#xff0c;推进多进程合理有序向前执行&#xff1b; 3.靠临…

Oracle入门(十二F)之表分区

转载自 oracle的 分表 详解 -----表分区一、分区表基础知识 (1) 表空间及分区表的概念表空间&#xff1a;是一个或多个数据文件的集合&#xff0c;所有的数据对象都存放在指定的表空间中&#xff0c;但主要存放的是表&#xff0c; 所以称作表空间。分区表&#xff1a; 当表中的…

工作展望简短_新一年工作展望短句

1、愿所有人认真告别现实的2020&#xff0c;认真迎接希望的2021。2、新的一年快开始了&#xff0c;年底一总结&#xff0c;发现自己只收获了年龄。3、来年&#xff0c;有趣有盼&#xff0c;福气不减。4、新的一年&#xff0c;心情&#xff0c;生活都像烟花一样灿烂。5、待凛冬离…

关于《在Windows与.NET平台上的持续交付实践》的问答录

《在Windows与.NET平台上的持续交付实践》&#xff08;Continuous Delivery with Windows and .Net&#xff09;&#xff08;免费下载&#xff09;是由Matthew Skelton与Chris ODell所编著的一本简短的书籍。对于在Windows与.NET环境中工作的开发者而言&#xff0c;本书可以说是…

14.信号量的代码实现

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.信号量基础知识&#xff0c;refer2 posts below. 12.进程同步与信号量_PacosonSWJTU的博客-CSDN博客1.本文内容总结自 B站 《操作系统-哈工大李治…

Oracle入门(十二G1)修改序列(Sequence)起始值的方法

转载自 Oracle修改序列&#xff08;Sequence&#xff09;起始值的方法Oracle 序列&#xff08;Sequence&#xff09;主要用于生成流水号&#xff0c;在应用中经常会用到&#xff0c;特别是作为ID值&#xff0c;拿来做表主键使用较多。 但是&#xff0c;有时需要修改序列初始值&…

weex安装环境_WEEX跨平台开发环境搭建

一、Weex简介大约两年前&#xff0c;为了写一本Weex的入门书籍&#xff0c;我花了几个月的时间学习了下Weex跨平台相关的知识。Weex 是阿里前端技术团队开源的一套跨平台开发方案&#xff0c;能以Web的开发体验构建高性能、可扩展的 Native 应用。简单来说&#xff0c;在集成了…

C#中使用gRPC

由于有NuGet&#xff0c;使得C#在配置项目时非常简单。 1. 在NuGet中添加ProtocolBuffer和gRPC引用 protocol buffer 3.0版本&#xff0c;在NuGet插件界面选择Include Prerelease&#xff0c;查找google protocol buffer。如果不选择include rerelease&#xff0c;查找到的prot…

15.操作系统死锁处理

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 【19.1】死锁场景 1&#xff09;死锁&#xff1a; 多个进程由于互相等待对方持有的资源而造成的谁也无法执行的情况&#xff1b; 1.1&#xff09;死…

使用VS Code 开发.NET Core 应用程序 部署到Linux 跨平台

前面讲解了VSCode开发调试 .NET Core。都只是在windows下运行。 .NET Core真正的核心是跨平台&#xff0c;我们现在来了解学习 .NET Core 跨平台。 在windows 下开发.NET Core 应用程序&#xff0c;然后部署到Linux 平台运行。 .NET Core RC2版基本上已经完成。 https://githu…

centos 并发请求数_linux实现高并发请求工具

使用工具abCentOS6默认安装CentOS7需要手动安装contos7下&#xff1a;1、联网&#xff1a;yum install httpd-tools2、未联网(没试过)&#xff1a;(1)进入cd /run/media/root/CentOS78664/Packages(路径跟centos6不同)(2)顺序安装apr-1.4.8-3.el7.86_64.rpmapr-util-1.5.2-6.el…

16.内存使用与分段

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 【1】 内存使用 【1.1】程序加载到内存 1&#xff09;内存使用&#xff1a;将程序放到内存中&#xff0c;PC寄存器指向开始地址&#xff1b; 2&…

Oracle入门(十三)之SQL的DML

数据操纵语言&#xff08;Data Manipulation Language, DML&#xff09;是SQL语言中&#xff0c;负责对数据库对象运行数据访问工作的指令集&#xff0c;以INSERT、UPDATE、DELETE三种指令为核心&#xff0c;分别代表插入、更新与删除&#xff0c;是开发以数据为中心的应用程序…

.NET Core 跨平台发布(dotnet publish)

.NET Core 跨平台发布(dotnet publish) ,无需安装.NET Core SDK,就可以运行。 前面讲解了.NET Core 的VSCode 开发。现在来讲讲发布&#xff08;dotnet publish&#xff09;。 .NET Core and ASP.NET Core 1.0 RC2 runtime and libraries 在五月中旬发布。 .NET Core and ASP.N…

Oracle入门(十三A)之Select

一、数据查询语句 &#xff08;1&#xff09;select语句完整的句法select 目标表的列名或列表达式序列from 基本表名和&#xff08;或&#xff09;视图序列[ where 行条件表达式 ][ group by 列名序列[ having 组条件表达式 ] ][ order by 列名[ asc|desc ]&#xff0c;… ] &a…

华为交换机ssh思科交换机_华为交换机 ssh 配置(极简版)

华为的 ssh 叫 STelnet(1)配置STelnet服务器功能及参数rsa local-key-pair create [1]stelnet server enable [2]undo ssh server keepalive disable [3][1] 创建密钥对&#xff0c;这个是必须的。可以选用 rsa dsa ecc 等加密算法&#xff0c;这里选择了最常用的rsa。输入命令…

17.内存分区与分页

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.程序使用内存的3个步骤&#xff1a; 步骤1&#xff1a;把程序分为多个段&#xff0c;包括代码段&#xff0c;数据段&#xff1b;这是编译要做的事…

漫谈C#编程语言在游戏领域的应用

0x00 前言 随着微软越来越开放&#xff0c;C#也变得越来越吸引人们的眼球。而在游戏行业中&#xff0c;C#也开始慢慢地获得了关注。这不&#xff0c; 网易绝代双娇手游团队已经全面使用.Net Core支持前后端统一C#开发&#xff0c;跨平台部署了。 所以&#xff0c;我们就来总结一…