进程同步与信号量(李治军操作系统课笔记6)

临界区:一次只允许一个进程进入

为什么需要临界区?两个生产者因竞争资源会产生随机的执行顺序,造成信号量的修改不当,信号量语义错误,所以需要保护信号量。

临界区代码的保护原则:
1、基本原则——互斥
2、有空让进
3、有限等待

临界区保护方法

1、轮换法:
在这里插入图片描述
但是,若P1被什么阻塞了,而P0结束了之后又不能继续进入临界区,导致两个都不在临界区。

2、标记法:
在这里插入图片描述
但是,因为变量不共享,所以看不到对方的标记。若如上图所示执行顺序,则会导致两个都不在临界区。

3、Peterson
在这里插入图片描述
其实就是在上面一种方法的基础上加上了一个共享变量(非共享+共享)
虽然turn是共享变量,但是不需要保护
可验证Peterson算法满足临界区三条原则

4、多个进程?——面包店算法
在这里插入图片描述
注意while(choosing);
也满足三条原则:
在这里插入图片描述
5、临界区的另一类保护解法:开关中断
在这里插入图片描述
cli=clear interuption ; sti=set interuption
原理是,在进入区阻止调度schedule的发生,而调度是因为中断,所以就是关闭中断
但在多CPU上不行,因为无法控制关闭所有cpu上的中断

6、硬件原子法
在这里插入图片描述
原子指令(一次执行,要不不做,做就做完):当TestAndSet得到结果时已经上锁

总结:

临界区域保护信号量的语义正确:面包店算法、开关中断、硬件原子……
信号量实现进程同步

进入睡眠的方式

有if和while两种进入睡眠方式,if非常直白,下面介绍while:
在这里插入图片描述
如何理解while?
先看sleep_on函数:
在这里插入图片描述
睡眠的实质,就是把自己写到阻塞队列上+改变自己的状态(也就是圈圈里的内容) ,然后再调用schedule
事实上,圈圈里的内容形成了一个睡眠队列:
在这里插入图片描述
tmp是局部变量,存储在当前进程的内核栈中,所以可以通过当前的task_struct找到内核栈中的tmp;tmp指向的是下一个task_struct,又可以通过下一个task_struct找到tmp,指向下下一个……由此形成队列

唤醒函数:
在这里插入图片描述
进程被唤醒后要从当时进入sleep的后面一句继续执行:
在这里插入图片描述
也就是if(tmp) tmp->state=0;
因为tmp指向睡眠队列中的下一个进程,所以会继续唤醒队列中下一个进程

while的好处:一次性全部唤醒,让schedule来决定switch_to谁,这样可以不按照先来先后,可以按优先级。

并且优先级最高的执行后,其他被唤醒的进程会继续上锁,不会一连串执行:
在这里插入图片描述
被唤醒后还要判断一遍while(),schedule切换到优先级最高的进程,执行bh->b_lock=1,而其他被唤醒的在进行while(bh->b_lock)判断时,就执行sleep_on了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值