阅读更多
1 程序并发执行
并发是所有问题产生的基础,同时并发是操作系统设计的基础
2 进程互斥
两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序
由于各进程要求使用共享资源(变量、文件等),而这些资源需要排他性使用各进程之间竞争使用这些资源——这一关系称为进程互斥
- 临界资源 critical resource:系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源或共享变量
- 临界区(互斥区) critical section(region):各个进程中对某个临界资源(共享变量)实施操作的程序片段
临界区的使用原则
- 没有进程在临界区时,想进入临界区的进程可进入
- 不允许两个进程同时处于其临界区中
- 临界区外运行的进程不得阻塞其他进程进入临界区
- 不得使进程无限期等待进入临界区
实现进程互斥的方案
- 软件方案
- Dekker解法、Peterson解法
- 硬件方案
- 屏蔽中断、TSL(XCHG)指令
3 进程互斥的软件解决方案
3.1 错误的解法
P
1 | ... |
Q
1 | ... |
如果进程P在执行完pturn = true;
后时间片用完,且进程Q在执行完qturn = true;
后时间片用完,那么之后P和Q将永远无法退出while循环了
3.2 DEKKER算法
DEKKER算法对上面那种错误的解法进行了改进,避免两个进程同时都无法退出while循环
P
1 | ... |
Q
1 | ... |
3.3 PETERSON算法
1 |
|
现在我们来分析一下while( turn == process && interested[other] == TRUE);
这个while循环条件的作用
interested[other] == TRUE
这个条件不满足,说明并没有发生竞争,只需要放行当前进程即可interested[other] == TRUE
这个条件如果在两个进程中都成立,说明两个进程存在竞争,那么接下来由turn的值来确定竞争的成功或失败。这里用的是turn == process
这个条件,即阻塞后修改turn变量的进程
4 进程互斥的硬件解决方案
4.1 硬件解法1-中断屏蔽
开关中断指令
1 | 执行“关中断”指令 |
优缺点:
- 简单,高效
- 代价高,限制CPU并发能力(临界区大小)
- 不适用于多处理器
- 适用于操作系统本身,不适于用户进程
4.2 硬件解法2-测试并加锁指令
TSL指令是一种需要硬件支持的方案。许多计算机,特别是那些为多处理机设计的计算机,都有一条指令叫做测试并上锁(TSL)
1 | TSL RX,LOCK |
这条指令的含义是,读取内存单元LOCK
中的内容到寄存器RX
中,并且为内存单元LOCK
重新设置一个非0值。TSL指令的操作被设计为不可分的,也就是说,整个读写操作都完成之前,其他进程是没办法访问LOCK这个内存单元的。这一点是通过锁定内存总线(lock memory bus)来实现的。
1 | enter_region |
4.3 硬件解法3-交换指令
XCHG指令交换两个寄存器,或者寄存器和内存变量的内容,且保证操作的原子性
1 | enter_region |
5 进程同步
进程同步:synchronization。指系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。具体地说,一个进程运行到某一点时,要求另一伙伴进程为它提供消息,在未获得消息之前,该进程进入阻塞态,获得消息后被唤醒进入就绪态
5.1 生产者消费者问题
问题描述:
- 一个或多个生产者生产某种类型的数据放置在缓冲区中
- 有消费者从缓冲区中取数据,每次取一项
- 只能有一个生产者或消费者对缓冲区进行操作
要解决的问题:
- 当缓冲区已满时,生产者不会继续向其中添加数据
- 当缓冲区为空时,消费者不会从中移走数据
6 信号量及P、V操作
什么是信号量
-
一个特殊变量
-
用于进程间传递信息的一个整数值
-
定义如下:
-
struc semaphore
{
int count;
queueType queue;
} -
信号量说明:semaphore s;
-
对信号量可以实施的操作:初始化、P和V(P、V分别是荷兰语的test(proberen)和increment(verhogen))
6.1 PV操作的定义
PV操作必须是原语(原子性)
1 | P(s) |
6.2 用PV操作解决进程间互斥问题
具体的流程如下
- 分析并发进程的关键活动,划定临界区
- 设置信号量 mutex,初值为1
- 在临界区前实施 P(mutex)
- 在临界区之后实施 V(mutex)
7 生产者消费者问题
1 |
|
交换过两个P操作的顺序可能造成死锁
8 读写者问题
问题描述:
- 多个进程共享一个数据区,这些进程分为两组:
- 读者进程:只读数据区中的数据
- 写者进程:只往数据区写数据
要求满足条件:
- 允许多个读者同时执行读操作
- 不允许多个写者同时操作
- 不允许读者、写者同时操作
8.1 第一类读写者问题:读者优先
如果读者执行:
- 无其他读者、写者,该读者可以读
- 若已有写者等,但有其他读者正在读,则该读者也可以读
- 若有写者正在写,该读者必须等
如果写者执行:
- 无其他读者、写者,该写者可以写
- 若有读者正在读,该写者等待
- 若有其他写者正在写,该写者等待
8.2 第一类读写者问题的解法
1 | void reader(void) |
9 参考
- 《MOOC-操作系统原理-陈向群》