【OS笔记07】:进程和线程5-进程的同步与互斥
文章目录
- 3.5 进程的同步与互斥
- 一、基本概念
- 1. 进程的同步与互斥
- 2. 临界资源和临界区
- 3. 进入临界区的准则
- 二、进程同步与互斥的异同
- 三、实现互斥的方法
- 1. 用锁操作原语实现互斥
- 2. 信号量上的P、V操作原语
- 1. 信号量 (Semaphore)
- 2. P、V操作的定义
- 3. P(S) 操作
- 4. V(S) 操作
3.5 进程的同步与互斥
一、基本概念
1. 进程的同步与互斥
- 并发关系:在并发系统中,各个进程由于共享资源、进程协作,会产生相互制约或依赖的关系。这种关系表现为:相互协作的同时,竞争着有限的资源。
- 两种制约关系:
- 同步 (Synchronization):进程间为了完成一个共同的目标,彼此存在相互合作的协同工作关系、有先后次序的直接制约关系。
- 互斥 (Mutual Exclusion):多个进程因不能同时访问临界资源而产生的间接制约关系。
- 重要性:在多道系统中,进程能否正确执行不仅取决于自身的正确性,能否与其他进程实现正确的同步和互斥也十分重要。
2. 临界资源和临界区
- 临界资源:一次只允许一个进程使用的资源。例如:打印机、共享变量等。若多个进程共享一个临界资源,则必须以互斥的方式使用。
- 例子:公用变量v,进程A要向v中写入数据,进程B要从v中读取数据,则v是A,B的临界资源,要交替使用。
- 临界区:访问临界资源的程序区域称为临界区。
3. 进入临界区的准则
- 忙则等待:每次至多有一个进程处于临界区。
- 空闲则入:当有若干个进程欲进入临界区时,应在有限的时间内使其进入。
- 有限等待:进程在临界区内仅逗留有限的时间。
二、进程同步与互斥的异同
- 相同点:两者都是并发进程在执行的时间顺序上,相互制约的表现。
- 不同点:
- 顺序:互斥的进程不规定进入临界区的先后顺序;同步的进程必须按照严格的先后次序执行。
- 感知:互斥的进程一般不知道对方存在;同步进程不仅知道对方存在,还需要与之通信。
例子:进程的同步
- 场景:计算进程和打印进程共享一个单缓冲区域,以完成计算和打印输出。
- 流程:
- 当计算进程完成计算,向缓冲区输出结果后;
- 计算进程向打印进程发送信号;
- 打印进程立即工作并打印结果;
- 打印进程取走结果后,向计算进程发出信号;
- 计算进程又可以把后续的计算结果写入缓冲区。
三、实现互斥的方法
1. 用锁操作原语实现互斥
为每类临界资源设置一个“锁”,即定义一个变量W:
-
w = 1
:表示锁打开。 -
w = 0
:表示锁关闭。 -
关锁原语
lock(w)
:while (w == 0); w = 0;
作用:当
W=0
时,反复测试w
的值,只有当W=1
时,才执行后面的程序段。 -
开锁原语
unlock(w)
:w = 1;
-
思考:这种方法能否解决同步问题?
- 答案是不能。
-
锁机制的缺点:
- 浪费CPU时间:在关锁原语中,会反复测试W的状态,浪费了处理机时间(忙等)。
- 功能局限:锁机制只能解决互斥问题,不能解决同步问题。
2. 信号量上的P、V操作原语
1. 信号量 (Semaphore)
信号量是一个由两个元素组成的结构型变量:
- 整型变量:表示该信号量的值。
- 信号量等待队列指针:指向该信号量等待队列中进程的PCB(进程控制块)。
整型变量的取值含义:
设信号量整型变量为S:
- 若
S > 0
,表示可用资源的实体个数。 - 若
S < 0
,其绝对值表示等待该资源的进程个数。
图片说明:图中展示了一个信号量,其值为-3,表示有3个进程正在等待该资源。指针指向这三个进程的PCB,形成一个等待队列。信号量的指针项可初始化为0,表示队列为空。
2. P、V操作的定义
P,V原语用于改变信号量的值,以达到系统资源的安全访问的目的。
P(S)
:表示有进程请求资源。V(S)
:表示有进程释放资源。- 原子性:P,V操作必须是“原语”,在单CPU系统中,通常在封锁中断的条件下执行P,V操作,确保其不可分割。
3. P(S) 操作
顺序执行下述两个动作:
- 信号量的值减1,即
S = S - 1
。 - 如果
S >= 0
,则该进程继续执行;
如果S < 0
,则:- 把该进程状态置为阻塞态。
- 将其PCB连入该信号量队列的末尾,进行等待。
图片说明:流程图展示了P操作的逻辑。入口后,s.value减1。然后判断s.value是否大于等于0,如果是,则继续执行;如果小于0,则调度进程进入等待队列,并转进程调度。
4. V(S) 操作
顺序执行下述两个动作:
- S值加1,即
S = S + 1
。 - 如果
S > 0
,则该进程继续运行;
如果S <= 0
,则唤醒信号量队列上的第一个PCB,然后该进程继续运行。
(注意:S<=0
时表示的是block
的进程个数,而不是资源个数)
图片说明:流程图展示了V操作的逻辑。入口后,s.value加1。然后判断s.value是否小于等于0,如果否,则继续执行;如果是,则唤醒等待队列中的一个进程,然后返回或转进程调度。