当前课程知识点:操作系统 >  第十八讲 信号量与管程 >  18.1 信号量 >  18.1 信号量

返回《操作系统》慕课在线视频课程列表

18.1 信号量在线视频

18.1 信号量

下一节:18.2 信号量使用

返回《操作系统》慕课在线视频列表

18.1 信号量课程教案、知识点、字幕

这一讲我们来介绍信号量和管程

信号量和管程

都是操作系统当中

提供的两种同步方法

那最开始我们说

因为我们在系统里呢

为了提高系统的并发性

所以我们引入了多进程和多线程

多线程的引入导致了

资源的共享使用和竞争

我们就会需要去

寻找解决的办法

这就是我们这里要同步

同步呢是为了协调多个进程

对共享数据的访问

我们把这个问题抽象出来

就变成是在任何一个时刻

那我们只能有一个线程

在执行临界区的代码

解决的办法呢

我们前面有这样几种说

我们可以基于底层的硬件实现

也可以在上面呢

有高层的抽象编程方法

那我们今天讲的信号量和管程

都是属于编程方法的两种

这是我们要最终解决的问题

我们需要协调各个线程

对临界资源的访问

然后我们的做法呢有这样几种

首先呢我们在最底层

希望来解决这个问题

你比如说禁止中断

那我也有 做原子操作

把读和修改这两个

变成一个原子操作

比如说我们TS指令

然后我们也有呢

完全基于最基本的读写操作

来构造出来的软件同步办法

这几类办法呢

我们把它都抽象成一个接口

说 就是我们这里前面说的锁

那用锁来申请临界区的进入

和在临界区完成之后那退出释放

好 这个机制能比较好地抽象

而它的实现呢

是依靠这底下这三种办法

这三种办法呢各有各的适用场合

然后有一个统一的锁机制之后

我们在上面能实现临界区的访问

今天我们要说的信号量呢

实际上就是跟锁机制

在同一个层次上的一种编程方法

它的做法是在操作系统的控制下

来做这件事情

信号量是操作系统提供的一种

协调共享资源访问的方法

那这种方法呢

它和我们前面讲到的

软件同步方法有什么区别呢

软件同步方法呢

实际上我们讨论的是平等的

线程之间的一种协调机制

那也就是说我如果用线程

通过软件方法来协调

谁进入临界区的时候

这些线程之间的位置是完全平等的

但是我们这里讲到的信号量呢

实际上它是由操作系统来负责管理的

操作系统作为管理者

它高于我们的进程

这做一个类比

就相当于是说我们在球场上踢球

一种是说两个球队一块踢

没有裁判

好 那这时候

我们有一套共同的规则

好 那这时候大家一起来踢

在这个过程当中呢

如果说有问题 我们照规则来

但实际上这时候呢

大家对规则理解

总是会有各种各样偏差

于是我们引入一个裁判

那裁判就是说

只要我们俩有分歧的时候

找到一个仲裁

由裁判说了算

那我们在这儿呢

实际上就是由操作系统

来做这个裁判

也就说两个进程协调

谁能使用临界区资源

由操作系统说了算

有了一个仲裁者

或者一个管理者之后呢

这种协调会变得比原来容易

好 在这种情况下

我们用一个信号量

来表示一类资源

信号量的取值呢

就是它的资源的数目

这种做法呢是最早

由一个荷兰科学家

叫Dijkstra 他提出的

那这个名字呢

我们在前面的数据结构里头

计算机科学里头

有很多他做出的贡献

这种办法呢在早期的操作系统当中

是最主要的同步机制

那目前呢在我们实际系统当中

这种用的相对来说比较少

但是它的重要性呢仍然是非常高的

它具体怎么做呢

信号量是一种抽象的数据类型

这个数据类型里头有三个内容

一个是一个整型变量

这个变量的取值呢

你可以理解为

你要共享的资源的数目

然后由两个原子操作

那这两个原子操作呢一个叫P操作

它是申请资源的时候要用的

我申请使用一个资源

那我把这个计数呢减一

也就相当于可用的资源数变少了

好 那这时候呢

就可能有一种情况是说

我来申请资源的时候

已经没有资源了

那这时候我就减成一个负数了

减成负数之后呢

我就需要等待另外的线程

用完这个资源之后

它释放了我才能用

好 那这时候呢它就进入等待状态

如果说不是这样 它是大于0的

也就相当于我拿到了相应资源

那我就可以使用了

好 这个P的出处呢是荷兰语

那最早这个科学家他做出来的

我们后续就延续这个提法了

然后反过来呢

我用完资源之后

我释放的时候一个V操作

V操作就是把计数加一

如果说你占用的是

由1变成0的那个资源

后面的线程再来的时候

那它就已经是负数了 它在等待

好 那这时候你加一之后

如果说它仍然是小于等于0的

那么这时候就说明

有另外一个线程

在等这个资源来使用

它目前处于等待状态

好 那这时候呢

我就唤醒相应的等待线程

好 这个V呢

也是跟P一样的

它来自于荷兰语

好 有了这两个之后

我们看这个它怎么来用的

我们做这样一个类比

也就说我假定有一个车站

车站有两个站台

一个站台呢可以停一列火车

进行上下乘客 或者说货物的装卸

好 我们在这儿呢把它抽象成

一个有两个资源的信号量

它做法什么样子呢

在这儿我们看到

这是车站的两个站台

好 没有任何站台被使用的时候

这时候任何一个火车

都是可以进来的

好 那这时候呢有一列火车

直接进到一个站台

然后这时候仍然有资源呢

这时候我这儿还是绿灯

好 等我把这资源占满了

我们通常情况下理解

这时候就有红灯

后面再来火车的话

它就停到这儿了

好 那这时候呢说再来火车

那实际上这时候呢 我就相当于

这地方的P操作减1再减1

这时候由2就减成0了

好 那这时候呢

再来第三辆的时候

它就出去等着了

等第一辆火车装卸完毕 它离开

好 那这时候加1

加1之后发现那

我这里头后面还有一个等着的

那这时候呢它就可以进来了

好 然后这时候呢两个都占用了

那我们在信号灯上看着就是红灯了

那我们实际上信号量的作用呢

就是类似于这个车站的控制流程

好 那我们说信号量它是

由一个整型变量加两个操作

那么这个整型变量呢

加上前面这个操作呢是

P操作和V操作对它进行保护

好这种保护之后呢

实际上我们就能做到

你对信号量中的整型变量的修改

你只能通过PV操作来完成

操作系统呢来保证

这个PV操作的原子性

那实际上这是我们前面说到的

操作系统在执行它的代码的时候

它的优先级高于我们

进程的用户代码

所以在这时候呢

它能保证它在执行过程当中

不受应用进程的代码执行的干扰

好 那这样就能保证它的原子性了

好 那这时候在执行过程当中呢

P操作有可能由于没有资源

而进入等待状态

V操作呢只会释放资源

处于等待状态的进程呢

变成是就绪状态

好 那这时候说

我们用信号量实现的同步

那这时候它能够做到公平吗

在我们实际用的时候呢

通常情况下假设它是公平的

在实际的系统当中呢

这个公平呢也会有些偏差的

那我们在这里说到的公平是指

我线程不会无限期的等待下去

它一定会结束

这是由于操作系统

在这里起的作用

那实际上我们在实际系统用的时候

这个P操作呢它也会说

在后面有一个等的最长时限的参数

那超时之后它直接错误返回

好 然后在这儿信号量的等待队列呢

我们是按先进先出排队

这一条呢实际上

在我们前面说到的锁机制里

自旋锁它实际上是做不到的

为什么呢 原因在于

我们自旋锁是需要占用CPU

随时随地去查

有可能临界区的使用者

退出的时候它刚改完

下一个进入者是谁去查

那它就能进去

如果说你运气不好

正好是这个资源变成有效

你去查的时候在你之前

就有一个人已经查过了

好 那么这时候呢

你就没有办法按照你

等待的这个顺序来做这一条

好 那我们看信号量的实现

我们把它定义成一个数据类型

好那这里头呢有一个变量 sem(semaphore)

然后有一个等待队列q

那这些呢都是在操作系统内核里头的

然后它定义两个操作

P操作和V操作

那在这里干些啥呢

进来之后它是信号量的变量减1

然后 如果你减完之后的值是小于0

那么这时候呢就说明我没有资源了

减到零是可以的

好 那它把这个线程呢

放到等待队列里头

并且呢阻塞

好 那这时候呢切换

好 等到我申请到了

那我就没有进入这个堵塞

我就直接进到临界区里去执行

那执行的过程当中呢

用完了退出的时候作为啥呢

信号量当中的变量加1

好 如果说加一之后还小于0

那就说实际上前面有人在等着

好 那这时候呢

我就从对应的等待队列里头

把相应的线程放到就绪队列里头

这和我们前面讲的

进程的状态的变迁

这样就结合起来了

然后它结束 它就干别的去了

那另一个 就可以进到临界区里头

好 这是我们说到信号量的实现

从这儿来讲好像这个东西很简单

和我们前面区别在哪

就是在于这一段代码

执行的原子性

它是由操作系统来保护的

为啥我们前面做不到这样一点呢

我这里头 减一和判断

那我们在前面

讨论软件方法的时候

最大的问题就在于

我减完一之后和这个判断这俩

中间可能会中断

好 由于这个中断

我们就有无数的麻烦

好 那这个时候现在有

操作系统在里头做保护了

好 我这两个代码

它的执行不会被打断

我们就会发现

这个地方 我变成一个原子之后

我的日子就好过多了

好 那这是我们说

信号量的基本原理

下面我们会去

用实际的例子

来说明它的使用方法

操作系统课程列表:

第零讲 在线教学环境准备

-0.1 Piazza讨论区

--piazza访问和使用

--html

-0.2 在线实验平台

--实验平台使用帮助

--平台使用帮助

--Gitlab使用帮助

--IBM内部账号初始化

-0.2在线实验平台

--Raw HTML

第一讲 操作系统概述

-1.1 课程概述

--视频

-第一讲 操作系统概述--练习

-1.2 教学安排

--视频

-1.3 什么是操作系统

--Video

-1.4 为什么学习操作系统,如何学习操作系统

--Video

-1.5 操作系统实例

--视频

-1.6 操作系统的演变

--视频

-1.7 操作系统结构

--视频

第二讲 实验零 操作系统实验环境准备

-2.1 前言和国内外现状

--2.1 前言和国内外现状

-2.2 OS实验目标

--2.2 OS实验目标

-2.3 8个OS实验概述

--2.3 8个OS实验概述

-2.4 实验环境搭建

--2.4 实验环境搭建

-2.5 x86-32硬件介绍

--2.5 x86-32硬件介绍

-2.6 ucore部分编程技巧

--2.6 ucore部分编程技巧

-2.7 演示实验操作过程

--2.7 演示实验操作过程

--Q6

--Q7

--Q10

第三讲 启动、中断、异常和系统调用

-3.1 BIOS

--3.1 BIOS

-3.2 系统启动流程

--3.2 系统启动流程

-3.3 中断、异常和系统调用比较

--3.3 中断、异常和系统调用比较

-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较

-3.4 系统调用

--3.4 系统调用

-第三讲 启动、中断、异常和系统调用--3.4 系统调用

-3.5 系统调用示例

--3.5 系统调用示例

-3.6 ucore+系统调用代码

--3.6 ucore+系统调用代码

第四讲 实验一 bootloader启动ucore os

-4.1 启动顺序

--4.1 启动顺序

-4.2 C函数调用的实现

--4.2 C函数调用的实现

-4.3 GCC内联汇编

--4.3 GCC内联汇编

-4.4 x86中断处理过程

--4.4 x86中断处理过程

-4.5 练习一

--4.5 练习一

-4.6 练习二

--4.6 练习二

-4.7 练习三

--4.7 练习三

-4.8 练习四 练习五

--4.8 练习四练习五

-4.9 练习六

--4.9 练习六

第五讲 物理内存管理: 连续内存分配

-5.1 计算机体系结构和内存层次

--5.1 计算机体系结构和内存层次

-5.2 地址空间和地址生成

--5.2 地址空间和地址生成

-5.3 连续内存分配

--5.3 连续内存分配

-5.4 碎片整理

--5.4 碎片整理

-5.5 伙伴系统

--5.5 伙伴系统

-第五讲 物理内存管理: 连续内存分配--5.6 练习

第六讲 物理内存管理: 非连续内存分配

-6.1 非连续内存分配的需求背景

--6.1 非连续内存分配的需求背景

-6.2 段式存储管理

-- 6.2 段式存储管理

-6.3 页式存储管理

--6.3 页式存储管理

-6.4 页表概述

--6.4 页表概述

-6.5 快表和多级页表

--6.5 快表和多级页表

-6.6 反置页表

--6.6 反置页表

-6.7 段页式存储管理

--6.7 段页式存储管理

-第六讲 物理内存管理: 非连续内存分配--6.8 练习

第七讲 实验二 物理内存管理

-7.1 了解x86保护模式中的特权级

--7.1 了解x86保护模式中的特权级

-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级

-7.2 了解特权级切换过程

--7.2 了解特权级切换过程

-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程

-7.3 了解段/页表

--7.3 了解段/页表

-第七讲 实验二 物理内存管理--7.3 了解段/页表

-7.4 了解UCORE建立段/页表

--7.4 了解ucore建立段/页表

-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表

-7.5 演示lab2实验环节

--7.5 演示lab2实验环节

第八讲 虚拟存储概念

-8.1 虚拟存储的需求背景

--8.1 虚拟存储的需求背景

-8.2 覆盖和交换

--8.2 覆盖和交换

-8.3 局部性原理

--8.3 局部性原理

-8.4 虚拟存储概念

--8.4 虚拟存储概念

-8.5 虚拟页式存储

--8.5 虚拟页式存储

-8.6 缺页异常

--8.6 缺页异常

第九讲 页面置换算法

-9.1 页面置换算法的概念

--9.1 页面置换算法的概念

-9.2 最优算法、先进先出算法和最近最久未使用算法

--9.2 最优算法、先进先出算法和最近最久未使用算法

-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法

-9.3 时钟置换算法和最不常用算法

--9.3 时钟置换算法和最不常用算法

-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法

-9.4 Belady现象和局部置换算法比较

--9.4 Belady现象和局部置换算法比较

-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较

-9.5 工作集置换算法

--9.5 工作集置换算法

-第九讲 页面置换算法--9.5 工作集置换算法

-9.6 缺页率置换算法

--9.6 缺页率置换算法

-第九讲 页面置换算法--9.6 缺页率置换算法

-9.7 抖动和负载控制

--9.7 抖动和负载控制

第十讲 实验三 虚拟内存管理

-10.1 实验目标:虚存管理

--10.1 实验目标:虚存管理

-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理

-10.2 回顾历史和了解当下

-- 10.2 回顾历史和了解当下

-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下

-10.3 处理流程、关键数据结构和功能

--10.3 处理流程、关键数据结构和功能

-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能

-10.4 页访问异常

--10.4 页访问异常

-第十讲 实验三 虚拟内存管理--10.4 页访问异常

-10.5 页换入换出机制

--10.5 页换入换出机制

-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制

第十一讲 进程和线程

-11.1 进程的概念

--11.1 进程的概念

-第十一讲 进程和线程--11.1 进程的概念

-11.2 进程控制块

--11.2 进程控制块

-第十一讲 进程和线程--11.2 进程控制块

-11.3 进程状态

--11.3 进程状态

-第十一讲 进程和线程--11.3 进程状态

-11.4 三状态进程模型

--11.4 三状态进程模型

-11.5 挂起进程模型

--11.5 挂起进程模型

-第十一讲 进程和线程--11.5 挂起进程模型

-11.6 线程的概念

--11.6 线程的概念

-第十一讲 进程和线程--11.6 线程的概念

-11.7 用户线程

--11.7 用户线程

-第十一讲 进程和线程--11.7 用户线程

-11.8 内核线程

--11.8 内核线程

-第十一讲 进程和线程--11.8 内核线程

第十二讲 进程控制

-12.1 进程切换

--12.1 进程切换

-第十二讲 进程控制--12.1 进程切换

-12.2 进程创建

--12.2 进程创建

-第十二讲 进程控制--12.2 进程创建

-12.3 进程加载

--12.3 进程加载

-第十二讲 进程控制--12.3 进程加载

-12.4 进程等待与退出

--12.4 进程等待与退出

-第十二讲 进程控制--12.4 进程等待与退出

第十三讲 实验四 内核线程管理

-13.1 总体介绍

--13.1 总体介绍

-13.2 关键数据结构

--13.2 关键数据结构

-13.3 执行流程

--13.3 执行流程

-13.4 实际操作

--13.4 实际操作

第十四讲 实验五 用户进程管理

-14.1 总体介绍

--14.1 总体介绍

-14.2 进程的内存布局

--14.2 进程的内存布局

-14.3 执行ELF格式的二进制代码-do_execve的实现

--14.3 执行ELF格式的二进制代码-do_execve的实现

-14.4 执行ELF格式的二进制代码-load_icode的实现

--14.4 执行ELF格式的二进制代码-load_icode的实现

-14.5 进程复制

--14.5 进程复制

-14.6 内存管理的copy-on-write机制

--14.6 内存管理的copy-on-write机制

第十五讲 处理机调度

-15.1 处理机调度概念

--15.1 处理机调度概念

-第十五讲 处理机调度--15.1 处理机调度概念

-15.2 调度准则

--15.2 调度准则

-15.3 先来先服务、短进程优先和最高响应比优先调度算法

--15.3 先来先服务、短进程优先和最高响应比优先调度算法

-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法

-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架

--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架

-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc

-15.5 实时调度和多处理器调度

--15.5 实时调度和多处理器调度

-第十五讲 处理机调度--15.5 实时调度和多处理器调度

-15.6 优先级反置

--15.6 优先级反置

-第十五讲 处理机调度--15.6 优先级反置

第十六讲 实验六 调度器

-16.1 总体介绍和调度过程

--16.1 总体介绍和调度过程

-16.2 调度算法支撑框架

--16.2 调度算法支撑框架

-16.3 时间片轮转调度算法

--16.3 时间片轮转调度算法

-16.4 Stride调度算法

--16.4 Stride调度算法

第十七讲 同步互斥

-17.1 背景

--17.1 背景

-17.2 现实生活中的同步问题

--17.2 现实生活中的同步问题

-第十七讲 同步互斥--17.2 现实生活中的同步问题

-17.3 临界区和禁用硬件中断同步方法

--17.3 临界区和禁用硬件中断同步方法

-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法

-17.4 基于软件的同步方法

--17.4 基于软件的同步方法

-第十七讲 同步互斥--17.4 基于软件的同步方法

-17.5 高级抽象的同步方法

--17.5 高级抽象的同步方法

-第十七讲 同步互斥--17.5 高级抽象的同步方法

第十八讲 信号量与管程

-18.1 信号量

--18.1 信号量

-第十八讲 信号量与管程--18.1 信号量

-18.2 信号量使用

--18.2 信号量使用

-第十八讲 信号量与管程--18.2 信号量使用

-18.3 管程

--18.3 管程

-第十八讲 信号量与管程--18.3 管程

-18.4 哲学家就餐问题

--18.4 哲学家就餐问题

-18.5 读者-写者问题

--18.5 读者-写者问题

第十九讲 实验七 同步互斥

-19.1 总体介绍

--19.1 总体介绍

-19.2 底层支撑

--19.2 底层支撑

-第十九讲 实验七 同步互斥--19.2 底层支撑

-19.3 信号量设计实现

--19.3 信号量设计实现

-第十九讲 实验七 同步互斥--19.3 信号量设计实现

-19.4 管程和条件变量设计实现

--19.4 管程和条件变量设计实现

-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现

-19.5 哲学家就餐问题

--19.5 哲学家就餐问题

第二十讲 死锁和进程通信

-20.1 死锁概念

--20.1 死锁概念

-第二十讲 死锁和进程通信--20.1 死锁概念

-20.2 死锁处理方法

--20.2 死锁处理方法

-第二十讲 死锁和进程通信--20.2 死锁处理方法

-20.3 银行家算法

--20.3 银行家算法

-第二十讲 死锁和进程通信--20.3 银行家算法

-20.4 死锁检测

--20.4 死锁检测

-第二十讲 死锁和进程通信--20.4 死锁检测

-20.5 进程通信概念

--20.5 进程通信概念

-第二十讲 死锁和进程通信--20.5 进程通信概念

-20.6 信号和管道

--20.6 信号和管道

-第二十讲 死锁和进程通信--20.6 信号和管道

-20.7 消息队列和共享内存

--20.7 消息队列和共享内存

-第二十讲 死锁和进程通信--20.7 消息队列和共享内存

第二十一讲 文件系统

-21.1 文件系统和文件

--21.1 文件系统和文件

-第二十一讲 文件系统--21.1 文件系统和文件

-21.2 文件描述符

--21.2 文件描述符

-第二十一讲 文件系统--21.2 文件描述符

-21.3 目录、文件别名和文件系统种类

--21.3 目录、文件别名和文件系统种类

-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类

-21.4 虚拟文件系统

--21.4 虚拟文件系统

-第二十一讲 文件系统--21.4 虚拟文件系统

-21.5 文件缓存和打开文件

--21.5 文件缓存和打开文件

-第二十一讲 文件系统--21.5 文件缓存和打开文件

-21.6 文件分配

--21.6 文件分配

-第二十一讲 文件系统--21.6 文件分配

-21.7 空闲空间管理和冗余磁盘阵列RAID

--21.7 空闲空间管理和冗余磁盘阵列RAID

-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID

第二十二讲 实验八 文件系统

-22.1 总体介绍

--22.1 总体介绍

-第二十二讲 实验八 文件系统--22.1 总体介绍

-22.2 ucore 文件系统架构

--22.2 ucore 文件系统架构

-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构

-22.3 Simple File System分析

--22.3 Simple File System分析

-第二十二讲 实验八 文件系统--22.3 Simple File System分析

-22.4 Virtual File System分析

--22.4 Virtual File System分析

-第二十二讲 实验八 文件系统--22.4 Virtual File System分

-22.5 I/O设备接口分析

--22.5 I/O设备接口分析

-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析

-22.6 执行流程分析

--22.6 执行流程分析

第二十三讲 I/O子系统

-23.1 I/O特点

--视频

-第二十三讲 I/O子系统--23.1 I/O特点

-23.2 I/O结构

--816C80A0F5E3B8809C33DC5901307461

-第二十三讲 I/O子系统--23.2 I/O结构

-23.3 I/O数据传输

--C58221E14388B9DB9C33DC5901307461

-第二十三讲 I/O子系统--23.3 I/O数据传输

-23.4 磁盘调度

--567A3F1FCBFB3F4C9C33DC5901307461

-第二十三讲 I/O子系统--23.4 磁盘调度

-23.5 磁盘缓存

--C327536B80D25CE79C33DC5901307461

-第二十三讲 I/O子系统--23.5 磁盘缓存

html

-html

--html

18.1 信号量笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。