14.信号量的代码实现

【README】

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

2.信号量基础知识,refer2 posts below.

12.进程同步与信号量_PacosonSWJTU的博客-CSDN博客1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;【1】https://blog.csdn.net/PacosonSWJTU/article/details/12553612013.信号量临界区保护_PacosonSWJTU的博客-CSDN博客1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;2.操作系统使用信号量实现进程同步(合作),走走停停,推进多进程合理有序向前执行; 3.靠临界区保护信号量,靠信号量实现进程同步;0)信号量1)问题 图解: 并发问题例子,empty = -1,但有2个生产者进程睡眠,这说明empty信号量的值是错误的;1)竞争条件: 图片解说:错误和调度顺序有关;2)解决竞争条件的方法 上图显示的执行顺序如下:时间进程代码或操作1P1检查并给empty上锁2P1.register=empthttps://blog.csdn.net/PacosonSWJTU/article/details/125542224


【1】信号量回顾

1)信号量定义:

  • 一个整型数字;通过对信号量的访问修改,实现多进程同步(合作),有序执行,(或互相等待,交替执行);

2)操作系统内部也是有信号量来实现多进程同步合作

  • 如一个进程操作磁盘,磁盘寻道时,该进程阻塞;
  • 一旦磁盘准备好数据后,通过中断通知cpu读取数据;则cpu唤醒上述进程读取数据;

3)借助信号量可以完成的工作

  • 工作1:借助信号量实现用户态的进程调度,实现上层应用程序间的同步(合作),交替执行;
  • 工作2:借助信号量实现内核态的进程调度;

4)信号量数据结构

  • 信号量数据结构包括 value值(信号量值), pcb队列(阻塞到信号量的进程队列);
  • 因为信号量的值要被所有进程看到,所以信号量在内核态;pcb是存储进程信息的数据结构;

【2】信号量代码

【2.1】代码1-打开信号量

 


Producer(item) {P(empty);  // P是生产者,empty减1 ...V(full);   // V是消费者,full 加1  
}// 用户态程序  producer.c 
main(){sd = sem_open("empty"); // 打开信号量 for (i=1 to 5) sem_wait(sd); // 写数据前,要看是否有空闲缓冲区; write(fd, &i, 4); // 把5个数字(1 2 3 4 5)	写入到磁盘,每个数字4个字节 
}// sem.c // 进入内核 
// 信号量结构体
typedef struct {char name[20]; // 信号量名称 int value; // 信号量值,一个整型变量 task_struct* queue; // 缓冲区队列
} semtable[20];// 系统调用:打开信号量或创建信号量
sys_sem_open(char *name) {在 semtable 中寻找name对上的项;没找到则创建;找到则返回对应下标;
}// 写数据前,要看是否有空闲缓冲区 
// 开关中断用于保护临界区  
sys_sem_wait(int sd) {cli();// 关中断,不允许cpu响应其他中断请求,// 不响应中断的目的是不响应时钟中断,从而不触发进程调度// 这里判断信号量用的是if ,目的是唤醒第1个进程 if (semtable[sd].value-- < 0) {// 设置自己为阻塞;// 将自己加入到 semtable[sd].queue 中; schedule(); // 切换到其他进程执行 }sti();	// 开中断
}

【2.2】代码2-读磁盘的信号量

 

// 读磁盘块 
bread(int dev, int block) 
{struct buffer_head* bh; // 申请一段空闲缓冲区内存(用于映射磁盘块空间)ll_rw_block(READ, bh); // 发起读命令 wait_on_buffer(bh);   // 等待磁盘响应,然后读数据到缓冲区bh 
}// 启动磁盘读以后睡眠,
// 等待磁盘读完由磁盘中断将其唤醒,也是一种同步
// 开关中断用于保护临界区,临界区保证同时仅有一个进程操作信号量
lock_buffer(buffer_head* bh) 
{cli(); // 关中断  // 这里判断信号量用的是 while,目的是唤醒所有阻塞进程 while(bh->b_lock)sleep_on(&bh->b_wait); // 如果被锁上,当前进程睡眠bh->b_lock = 1; // b_lock也是信号量;这里上锁; 数据读完后,中断服务程序解锁;  sti(); // 开中断 
}// 当前进程阻塞(睡眠),切换到其他进程 
void sleep_on(struct task_struct **p) 
{struct task_struct *tmp;tmp = *p;*p = current;current->state = TASK_UNINTERRUPTIBLE; // 把进程状态更新为阻塞态 schedule(); // 调度, 底层调用switch_to()以切换到其他进程执行; if (tmp) tmp->state = 0; 
}

【2.3】代码3-sleep_on形成的队列


【2.4】 代码4-从队列中唤醒阻塞进程

 


// 对阻塞进程的唤醒 (通过磁盘中断来唤醒) 
static void read_intr(void) 
{...end_request(1); // 磁盘准备数据完成后调用 
}end_request(int uptodate) 
{...unlock_buffer(CURRENT->bh);  // 解锁缓冲区 
}// 解锁缓冲区 
unlock_buffer(struct buffer_head *bh) 
{bh->b_lock = 0;wake_up(&bh->b_wait); // 唤醒阻塞的进程 
}
// 唤醒阻塞的进程  
wake_up(struct task_struct **p) 
{if (p && *p) {(**p).state = 0; // 把阻塞进程的state设置为0,该进程就变成就绪态了 *p = NULL;  }
}


注意:代码1用 if 判断信号量,代码2用 while 判断信号量,注意两者的区别

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

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

相关文章

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;我们就来总结一…

dex工具与transform_Android Studio打包程序时出现transformClassesWithDexForRelease错误

百度半天.没找到直接原因..国外网站上有写这个错误的..国内的真心没找到..英语水平有太低..实在没看懂怎么搞..后来发现clean项目的时候是提示如下错误:Information:Gradle tasks [clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:mockableAndr…

18.多级页表与快表

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.操作系统内存管理&#xff1a;分页机制多级页表快表来实现&#xff1b; 【0】分页的问题 1&#xff09;分页的问题&#xff08;大页表&#xff09…

Oracle入门(十三A1)之替换变量,变量名,变量名

转载自 Oracle中的替换变量&#xff0c;&变量名&#xff0c;&&变量名替换变量&#xff08;仅用于SQL *Plus或者用于原理和SQL *Plus相同的开发工具&#xff09;&#xff1a;临时存储值利用它可以达到创建通用脚本的目的利用它可以达到和用户交互&#xff0c;故在SQ…

常用API接口签名验证参考

项目中常用的API接口签名验证方法&#xff1a; 1. 给app分配对应的key、secret2. Sign签名&#xff0c;调用API 时需要对请求参数进行签名验证&#xff0c;签名方式如下&#xff1a;  a. 按照请求参数名称将所有请求参数按照字母先后顺序排序得到&#xff1a;keyvaluekeyvalu…

19.段页结合的实际内存管理

【README】 1.本文内容总结自 B站 《操作系统-哈工大李治军老师》&#xff0c;内容非常棒&#xff0c;墙裂推荐&#xff1b; 2.段与页 段&#xff1a; 用户程序采用分段结构&#xff1b;页&#xff1a; 操作系统采用分页机制管理物理内存&#xff1b;段页结合&#xff1a;程…

python中变量怎么定义_python中的变量的使用定义以及使用规则

本篇包括14章内容&#xff0c;系统介绍了Python语言的基础知识。内容包括Python基础语法、数据类型和类型转换、运算符、流程控制(分支结构循环结构)、数据结构(列表生成式)、函数的定义及使用、异常处理、迭代器生成器、偏函数、python中的模块和包、python标准内置库os以及使…

Oracle入门(十二G)之序列

序列&#xff08;SEQUENCE&#xff09;序列是一数据库对象&#xff0c;利用它可生成唯一的整数。由于它属于可共享对象&#xff0c;所以允许多个用户访问。一般情况下&#xff0c;序列用于创建主键值。 序列号的存储和生成与表无关。因此&#xff0c;同一序列可以用于多个表。 …