操作系统笔记(3)——同步与互斥
启蒙篇
基础篇
- 并发性:
cpu
可以分时间段交替执行不同程序代码
1.临界资源&临界区
临界资源:一次只能被一个进程所使用的资源
- eg:
- 硬件——打印机、网卡、键盘
- 软件——共享变量
- eg:
临界区:每个进程中访问临界资源的那段代码成为临界区
- 每个进程在进入临界区之前,应先对欲访问的临界资源进行检查,看他是否正在被访问
- 若是则进程不能进入临界区
- 若否则可以进入访问,并设置其正被访问的标志
- 每个进程在进入临界区之前,应先对欲访问的临界资源进行检查,看他是否正在被访问
2.同步与互斥
进程(线程)之间的两种关系:同步与互斥。
- 所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。
- 所谓同步,是指散布在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。
同步是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!
总结
- 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
- 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
3.互斥的实现
硬件方法
中断屏蔽法
- 提要:
- 调度时机大概可以分为三种
- 程序结束时 —— 已经没有竞争对手,不需要互斥
I/O
请求时- 时间片用完时
- 这三种都属于中断
只允许
cpu
为一个进程服务中断屏蔽法本质上是将
cpu
“麻痹”,令其无法接收到中断信号,如此一来就无法完成切换操作,自然可以让cpu
只服务于一个进程此种方法只能作用于后两种:
I/O
请求和时间片用完
原子硬件指令法(Test And Set、Swap)
Test And Set、Swap
是一个硬件电路,特点是不会受到中断信号的干扰,无论如何都会执行完指定段代码
软件方法
单标志法
- 轮流传递的思想(令牌环网)
- 生死系于别人(缺点)
- 当
turn
的编号与自己编号相符时则使用,使用完毕后更改编号传递至下一个人
双标志先检查法 —— 每个人都有自己的标志(无需等待令牌了)
- 通过设置
flag
值的真伪来判断对方是否要使用cpu
。若对方不使用则自己用 - 可以理解为两人相互谦让,但是比较容易产生
bug
- 若双方看对方均为
false
,则同时请求使用cpu
时也会产生冲突 - 若双方看对方均为
true
,则陷入等待
- 若双方看对方均为
- 通过设置
双标志后检查法
- 一开始就将
flag
设置为true
,此后再进行判断对方是否请求 - 可以理解为双方争执,可能会出现争执不下而都无法使用(无限等待 + 饥饿)
- 一开始就将
Peterson's
算法(真正实现互斥)双方开始将
flag
置于true
,但夺取cpu
资源之前会观察对方,避免太过“强势”而造成的无限等待和饥饿问题Faker(){while(1){flag[0] = true; //资源是自己的turn = 1; //留一手,如果你也想要可以先让给你white(flag[1] && turn == 1){if(gun == 1){gun = Faker;}else{;}flag[0] = false;}} }Rookie(){while(1){flag[0] = true; //资源是自己的turn = 1; //留一手,如果你也想要可以先让给你white(flag[0] && turn == 0){if(gun == 1){gun = Rookie;}else{;}flag[0] = false;}} }
如代码所示,
cpu
上优先级上Rookie
更高后台更改数据为最终的数据
4.信号量
由来
- P、V操作:
- P(等待):等待进入临界区
- V(释放):从临界区中出来释放资源
工作原理
typedef struct{int value; //值struct process *L; //阻塞队列 PCB
}semephore; //信号量//S.value 的初始值很重要,可以决定最多有几个进程同时运行
//S.value > 0 时 有资源,直接入驻。资源数减一
//S.value = 0 时 刚好无资源,排队等待
//S.value < 0 时 无资源,排队,自己是负几就排第几void wait(semephore S){S.value--;if(S.value < 0){//本进程放弃cpu,进队本信号量的阻塞队列}
}
void signal(semephore S){S.value++;if(S.value <= 0){//唤醒本信号量队列的第一个进程,让其等待获取cpu继续运行}
}
信号量实现同步
此前我们提到了判别符S,其初值尤为重要,可以决定最多有几个进程同时运行
S > 0
时 有资源,直接入驻。资源数减一
S = 0
时 刚好无资源,排队等待
S < 0
时 无资源,排队,自己是负几就排第几- eg:此题我们来通过控制信号量的值完成同步。此题中
S = 0
// 同步模板
P0(){ P1(){while(1){ while(1){P(S); ........ V(S)} }
} }
假使先运行P0
代码,进入while
循环后发现执行了P
(等待)操作,资源数(S
)减一,但由于此时S
值为0
,故此进程进入等待队列,代码继续向后执行。直至操作到P1
代码时,执行了V
操作,资源数(S
)加一,等待队列中的P0
得到资源可以开始执行。故执行完P1
后执行P0
,如此即通过信号量实现的同步操作。
信号量实现互斥
- eg:通过控制信号量实现互斥。此题中
S(Semphore) = 1
// 互斥模板
//先执行P0,期间执行P1()
P0(){ P1(){while(1){ while(1){P(S); P(S);.... //临界区 .... //临界区V(S); V(S);} }
} }
同步互斥的小口诀
- 画图理解题目
- 判断题目类型
- 分析进程数目,填写进程模板
- 补充基本代码
- 补充
PV
代码 - 检查调整代码
5.例题
生产者与消费者
例1:
妈妈每次放一个苹果到桌子上,你每次从桌子上取一个苹果。但放苹果和取苹果不能同时进行,且桌子上最多放10个苹果。请用PV
操作实现同步互斥。
分析:生产者只关心剩余空间,消费者只关心已占有空间
semephore full = 0 // 开始占有空间
semephore empty = 10 // 开始空余空间
semephore S = 1 //实现互斥的信号量(初始值只能为1)You(){ Mom(){while(1){ while(1){P(full); P(empty) //是否有剩余空间// 信号量PV操作夹着互斥部分的代码(题设要求取放操作不能同时进行)// 只要是和数据打交道并且会影响容器的动作钱后都应加上PV信号量操作P(S) P(S)// 取一个苹果 // 放1个苹果V(S) V(S)V(empty) V(full)} }
} }
例2:
桌子上有个盘子,每次只能放入一个水果。妈妈放桔子,爸爸放苹果。儿子吃橘子,女儿吃苹果。盘子为空时爸爸或妈妈才能放水果,盘子不为空时儿子和女儿才能吃水果。
- 分析:
semephore orange = 0
semephore apple = 0
semephore plate = 1
semephore mutex = 1Mom(){ Dad(){while(1){ while(1){P(plate); P(plate) // 盘子是否为空//互斥,用PV操作包裹P(mutex) P(mutex)// 放1个桔子 // 放1个苹果V(mutex) V(mutex)V(orange) V(apple)} }
} }Son(){ Daughter(){while(1){ while(1){P(orange); P(apple)P(mutex) P(mutex)// 取1个桔子 // 取1个苹果V(mutex) V(mutex)V(plate) V(plate)} }
} }
例3:
有A
、B
两人通过信箱辩论。每个人都从自己的信箱里取得对方的问题,将答案和新的问题组成一个邮件放入对方的信箱中。假设A
信箱可装M
封邮件,B
的可装N
封邮件。初始时A
信箱有x
封,B
信箱有y
封。辩论者每次只取一封邮件,请用PV
操作实现其辩论过程,并解释信号量的初值和含义
分析:
A
作为生产者:B
的邮箱中剩余空间B
作为生产者:A
的邮箱中剩余空间A
作为消费者:自己的邮箱中有多少封信B
作为消费者:自己的邮箱中有多少封信
semephore mutex_A = mutex_B = 1; semephore full_A = x; // 已有邮件数量 semephore full_B = y; semephore empty_A = M-x; // 剩余空间 semephore empty_B = M-y;A(){ B(){while(1){ while(1){P(full_A) //查看信箱中是否有信 P(full_B) // 查看自己信箱中还有没有邮件P(mytex_A) P(mutex_B)从自己邮箱取信 从自己邮箱取信V(mutex_A) V(mutex_B)V(empty_A) //增加剩余空间 V(empty_B) //增加剩余空间P(empty_B) // 查看B信箱中的空间 P(empty_A) // 查看A信箱的空间P(mytex_B) P(mutex_A)向B邮箱投信 向A邮箱投信V(mutex_B) V(mutex_A)V(full_B) // 增加B信箱中的邮件数 V(full_A) //增加A信箱中的邮件数量} } } }
例4:
系统中有多个生产者和消费者,共享一个能存放1000
件产品的环形缓冲区(初为空)。当缓冲区未满时生产者可放入生产的一个产品,否则等待。当缓冲区未空时,消费者进程可取走一件产品,否则等待。要求一个消费者从缓冲区连续取走10件产品后,其他消费者才能取产品。请用PV
操作实现该流程并解释信号量含义
- 分析
- 生产者(i) —— 是否还有剩余空间
- 生产者(j) —— 是否还有剩余空间
- 消费者(m) —— 是否还有物件(物件数量)
- 消费者(n) —— 是否还有物件(物件数量)
semephore empty = 1000; // 剩余空间量
semephore full = 0; // 占用空间量
semephore mutex = 1;i(){while(1){P(empty);P(mutex);放一件产品;V(mutex);V(full);}
}m(){while(1){P(mutex); //取时不可被打断,故加锁for(int i=0; i<10; i++){P(full);P(mutex);放一件产品;V(mutex);V(empty);}V(mutex);}
}
读者与写者
例1:
有读写两组进程,共享一个文件。多个读者可同时访问文件,但多个写者不能同时访问文件。读者和写者亦不能同时访问文件。
分析:
读者团:只有第一个读者才会创建一个读者团。后边到来的读者则会加入。而最后一个读者完成读操作后则会释放文件。
writer(){while(1){P(mutex);写;V(mutex);} }reader(){while(1){P(mutex)if(count == 0){ // 若他是第一个读者则申请资源(文件),创建读者团P(S); // 申请资源count++;}V(mutex);读;P(mutex);count--;if(count == 0){ // 若他是最后一个读者,走时释放资源(文件)V(S) // 释放资源}V(mutex);} }
例2:
猴子过峡谷:横跨峡谷有一根绳索。猴子通过绳索过峡谷。只要他们朝着相同的方向,同一时刻可以有多只猴子通过。但如果相反方向同时有猴子通过则产生死锁。如果一只猴子想过峡谷,必须看是否有相反方向的猴子通过。请用PV
操作解决问题
分析
- 第一只:桥是否被占用
- 只增加数量
- 最后一只:释放桥资源
MonkeyClub(){while(1){P(mutex)if(count == 0){ // 若他是第一个猴子则申请资源(绳索),创建猴团P(S); // 申请资源count++;}V(mutex);读;P(mutex);count--;if(count == 0){ // 若他是最后一个猴,走时释放资源(绳索)V(S) // 释放资源}V(mutex);} }
操作系统笔记(3)——同步与互斥相关推荐
- linux操作系统之线程同步及互斥量
(1)线程同步 1)线程同步:指一个线程发出某一个功能运行时,在运行还没有结束的时候,该调用不返回.同时其它线程为保证数据的一致性,不能调用该功能. 2)多个控制流共同操作一个共享资源的时候,都需要同 ...
- 操作系统习题3—进程的互斥与同步
操作系统习题3-进程的互斥与同步 1.例举两个现实生活中需要同步与互斥的例子. 我们去吃自助餐时,店里的厨师会在后台厨房制作食物,然后将食物运送到公共饮食区域,让顾客自行挑选.如果公共饮食区域的食物都 ...
- (操作系统题目题型总结)第三章:同步与互斥
费翔林课本习题 思考题 1.试述顺序程序设计的特点以及采用顺序程序设计的优缺点 [答案] 特点: 执行的顺序性:一个程序在处理器上是严格按序执行的,每个操作必须在下一个操作开始前结束 环境的封闭性:运 ...
- 操作系统课程设计-线程和进程的同步与互斥
操作系统的课程设计 多线程和多进程同步方法解决水果分配问题: 水果分配的问题: 桌上有一只盘子,每次只能放入5只水果.爸爸专放苹果, 妈妈专放橘子,一个儿子专等吃盘子中的橘子,一个女儿专等吃盘子中的苹 ...
- 【操作系统】同步和互斥
进程之间可能存在同步和互斥的制约关系. 同步指的是为了完成某种任务而建立的两个或多个进程,这些进程因为需要在某些位置上协调它们的工作次序而等待.传递消息所产生的的制约关系. 互斥指的是一个进程进入临界 ...
- OS学习笔记-17(清华大学慕课)进程的同步和互斥
进程的同步和互斥 背景 多个进程一起执行有很多好处,但执行时容易产生资源共享的问题 进程的交互 互斥(一个进程占用某资源,则其他进程不能使用该资源) 死锁(多个进程占用各自部分资源,形成循环等待) 饥 ...
- 操作系统二轮复习(进程的同步与互斥)
文章目录 进程互斥与同步四原则 进程互斥的软件实现方法 单标志法(空闲让进) 双标志先检查法(忙则等待) 双标志后检查法(空闲让进.有限等待) 皮特森算法(让权等待) 小结 进程互斥的硬件实现方法 中 ...
- 【OS 学习笔记】什么是同步、互斥?
一.背景 最近正在复习OS,为了更好理解其原理,便通过写博客来加深理解.由于知识水平有限,可能存在一些疏漏和不恰当之处,希望大佬们批评指点. 二.同步机制 什么是同步和互斥? 同步Synchroniz ...
- 操作系统之信号量机制以及使用信号量实现进程(线程)同步和互斥
1.同步和互斥: 同步(直接制约关系):指的是完成同一任务的伙伴进程间,因需要协调它们的工作而等待.传递信息等.(z(进程1)和m(进程2)需要完成买东西的任务,z把钱给了m,m才能去买东西.) 互斥 ...
最新文章
- html按钮线性炫光,6分钟实现CSS炫光倒影按钮 html+css
- 总结:ps aux指令
- android 缓存文件的工具类,总结的一些android公共库,包含缓存(图片缓存、预取缓存)、...
- Installshield获取安装包版本的系统变量是IFX_PRODUCT_VERSION
- 移动流量转赠给好友_私域流量的五大认知误区
- 论文浅尝 | 基于知识库的自然语言理解 03#
- keil C对lib封装库反汇编成C语言,Keil软件“C语言”及“汇编”混编 —— 相关知识整理.doc...
- arduino char*转string_Java 中 String 类的常用方法汇总
- mysql客户端重庆_MySQL:MySQL工具以及5.7mysqlbinlog|mysql速度极慢问题
- eclipse快捷键_Eclipse快捷键
- 19.(cesium之家)cesium接入加载3D城市建筑物(离线)
- Markdown编辑器-MarkdownPad下载与安装(win10)
- 刘乾四川大学计算机学院刘乾,计算机学院2011~2012学年-四川大学计算机学院.doc...
- python 计算众数、中位数、分位数、偏度、峰度
- 古马其顿国王-亚历山大
- 学习java有哪些书籍推荐?学java看什么书和资料?
- 消息系统(ActiveMQ)
- 26.什么是梯度爆炸
- WPS文档消除格式并消除大片空白格
- Linux虚拟机断电后开机出现:Entering emeryency mode. Exit the shell to continue.
热门文章
- 王唯佳被南开计算机学院录取,被南开录取!沈阳庞贝病少年王唯佳,祝贺你!辽宁日报 昨天辽宁...
- 《四维全息算法》9--四维全息算法的基本思路是什么?股市数据是具有分形迭代特征的随机游走
- 读书笔记:Python编程——从入门到实践
- 这些朋友更适合苹果电脑,你了解吗?
- ziheng - 测手速游戏
- 用Python 操作 Excel,这篇文章别错过了!(超全总结)
- JavaScript中一个等号、二个等号、 三个等号 的区别
- Ubuntu使用笔记(Talk is cheap,show me the code.)
- java线程占用的空间_linux服务器查询java线程占用的资源-Go语言中文社区
- 非计算机专业买几寸电脑好,学习计算机网路技术专业,是不是需要买电脑啊