【操作系统复习】Unit2-2:进程的同步与互斥

2.1 同步与互斥问题

进程互斥(间接制约)

  • 两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥。

进程同步(直接制约)

  • 系统中各进程之间能有效地共享资源和相互合作,从而使程序的执行具有可再现性的过程称为进程同步。
  • 进程同步是进程间的一种刻意安排的直接制约关系。即为完成同一个任务的各进程之间,因需要协调它们的工作而相互等待、相互交换信息所产生的制约关系

同步与互斥区别与联系

  • 互斥:同时只允许一个访问者对其访问,无序访问
  • 同步:在互斥的基础上(大多数情况),有序访问。

互斥区管理应满足的条件

  • 空闲让进、忙则等待、有限等待、让权等待
  1. 当一个进程运行在它的临界区外面时,不能妨碍其他的进程进入临界区(Progress)

临界资源:一次仅允许一个进程使用的进程。可把访问临界资源的过程分为四个部分

  • 进入区:检查是否可进入临界区
  • 临界区:进程中访问临街资源的那段代码,又称临界段
  • 退出区:将正在访问临界区的标志清除
  • 剩余区:代码中的其他部分

2.2 基于忙等待的互斥方法

软件方法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
PS:上面这个方法 ∈ \in 双标志后检查法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Lamport Bakery Algorithm(面包店算法)

硬件方法

中断屏蔽

  • 中断屏蔽方法:使用“开关中断”指令。
    • 执行“关中断”指令,进入临界区操作;退出临界区之前,执行“开中断”指令。
  • 优点:简单,方便
  • 缺点:不适用于多CPU系统:往往会带来很大的性能损失;只适合于操作系统内核进程,不适用于用户进程(影响时钟)

使用test and set指令——(硬件逻辑直接实现,不会被中断)

  • TS(test-and-set )是一种不可中断的基本原语(指令)。它会写值到某个内存位置并传回其旧值。在多进程可同时存取内存的情况下,如果一个进程正在执行检查并设置,在它执行完成前,其它的进程不可以执行检查并设置。

自旋锁Spinlocks

  • 利用test_and_set硬件原语提供互斥支持
  • 通过对总线的锁定实现对某个内存位置的原子读与更新

使用swap指令/XCHG指令——(硬件逻辑直接实现,不会被中断)

  • swap(对换)指令与TSL指令一样,是不会被中断的原子指令,其功能是交换两个字的内容
  • 采用Swap指令与采用TSL指令类似,也会由于循环交换两个变量,造成忙等的情况。

硬件方法的优点:适用于任意数目的进程;简单、容易验证其正确性。

硬件方法的缺点:不能实现让权等待,可能导致“饥饿”

几个算法的共性问题

  • 当一个进程想进入临界区时,先检查是否允许进入,若不允许,则该进程将原地等待,直到允许为止

2.3 基于信号量的方法

基本思路:使用一种新的变量类型

信号量只能通过初始化和两个标准的原语来访问,作为OS核心代码执行,不受进程调度的打断(低级通信原语)

整型信号量:

P(S):while S <= 0 do skip	//不满足让权等待,而是“忙等”
	S := S-1;
V(S): S := S+1

计数信号量机制

Type semaphore = record
	value : integer;
	L : list of process;
end

Procedure P(S)
	var S : semaphore;
	begin
		S.value --;
		if (S.value < 0) then block(S.L);
	end

Procedure V(S)
	var S : semaphore;
	begin
		S.value ++;
		if (S.value <= 0) then wakeup(S.L);
	end

物理意义

  • S.value为正时表示资源的个数
  • S.value为负时,表示等待进程的个数
  • P操作分配资源,V操作释放资源

信号量机制的实现

  • 原子性问题:关中断、TS指令等
  • PCB链表形式

信号量的应用

  • 互斥:令S=1。
  • 同步:令S=0;

举个栗子【前趋图】 、
在这里插入图片描述

多进程同步原语:屏障Barriers

信号量集——控制同时需要多个资源的互斥访问(加锁顺序不当会导致死锁)

  • AND型信号量集机制

  • 一般信号量集机制

PV操作的优缺点

  1. 优点:简单,表达能力强(可用PV操作解决任何同步互斥问题
  2. 缺点
    1. 不够安全,同步操作分散在各个进程中,使用不当会发生死锁;
    2. 遇到复杂同步互斥问题实现复杂
    3. 加重了编程的负担

2.4 基于管程的同步与互斥

【王道P96】

管程:

  1. 把分散的临界区集中起来,为每个可共享资源设计一个专门机构统一管理各进程对资源的访问,这个专门机构称为管程。
  2. 是一种高级同步原语
  3. 以函数库的形式实现(不是操作系统实现),比信号量好控,无需程序员自己实现互斥

一个管程是由过程、变量、数据结构等组成的一个集合,它们组成了一个特殊的模块或者软件包

  1. 局部于该管程的共享数据:资源状态
  2. 局部于该管程的若干过程:对数据的操作

管程把对共享资源的操作封装起来(类似java的类),每次仅允许一个进程进入管程,从而实现进程互斥。

管程的实现

  1. 局部控制变量(临界资源):一组局部于管程的控制变量

  2. 初始化代码:对控制变量进行初始化的代码

  3. 操作原语(互斥):对控制变量和临界资源进行操作的一组原语过程(程序代码),是访问该管程的唯一途径

  4. 条件变量(同步):管程将阻塞原因定义为条件变量,当定义一个条件变量x时,系统就建立一个相应的等待队列,对条件变量只有两种操作:

    • wait(x):把调用者进程放入x的等待队列

    • signal(x):唤醒x等待队列中的一个进程

    • 表示一种等待原因,并不取具体数值——相当于每个原因对应一个队列

与信号量的区别

  1. 条件变量是“没有值”的,仅实现了“排队等待”功能,PV操作的是可增减信号量。信号量的值反映了剩余资源数,而管程中,剩余资源数用共享数据结构记录

    • wait操作一定会阻塞当前进程;但P操作只有当信号量的值小于0时才会阻塞

    • 如果没有等待的进程,signal将丢失;而V操作增加了信号量的值,不会丢失。

  2. 访问条件变量必须具有管道的锁

多个进程同时在管程出现

2.5 经典的进程同步与互斥问题

生产者-消费者问题

问题描述:“生产者”进程不断写入,而“消费者”进程不断读出;共享缓冲区共有N个;任何时刻只能有一个进程可对共享缓冲区进行操作。

在这里插入图片描述

用PV操作(信号量)解决生产者消费者问题

//信号量设置
semaphore mutex = 1;//互斥
semaphore empty = N;//空闲数量
semaphore full = 0;//产品数量
//实际上,full和empty是同一个含义,full+empty = N;

//生产者
while (true) {
    生产产品
    P(empty);
	P(mutex);
	one >> buffer;
	V(mutex);
	V(full);
}

//消费者
while(true) {
    P(full);
	P(mutex);
	one << buffer;
	V(mutex);
	V(empty);
    消费产品
}

能否把对mutex的PV操作放在最外面?不行,会出现死锁【加锁是必要的,但尽量的小】

如果仅交换两个V,可以。

用管程解决生产者消费者问题

  • 在这里插入图片描述

读者-写者问题

问题描述:对共享资源的读写操作,任一时刻“写者”最多只允许一个,而“读者”则允许多个,即“读-写”互斥,“写-写”互斥,“读-读”允许

采用信号量机制

  • 基本框架

    在这里插入图片描述

    wmutex表示“允许写”,初值为1

    公共变量readcount表示“正在读”的进程数,初值是0;

    mutex表示对readcount的互斥操作,初值是1

在这里插入图片描述
(只有第一个读者才会加wmutex锁)

之前(对读者有利)算法

  • 只要有度进程活跃,随后而来的读进程都被允许访问文件,写进程可能被“饿死”

  • 从读者、写者自身角度总结几条规则

  • 写者:

    • 开始后,没有其他写者、读者可以进入
    • 必须确保没有正在读的读者,才能开始写
    • 写完之后允许其他读写者进入
  • 读者开始读之前需要确保:

    • 第一个读者开始读,到最后一个读者结束读之间不允许有写进程进入

对写者有利/读写公平的算法

  • 写者出现后,新读者不允许抢在该写者之前进行读操作。也就是说:写者出现后,后续读者不允许执行rcount=rcount+1
  • 需要增加一个互斥信号量

读写公平的算法

在这里插入图片描述

不能放在read之后,放在read后会导致读者之间互斥

哲学家进餐问题

解题思路:

  • 至多只允许四个哲学家同时(尝试)进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐。设置信号量room=4。(破除资源互斥
  • 对筷子进行编号,奇数号先拿左,再拿右;偶数号相反。(破除循环等待
  • 同时拿起两根筷子,否则不拿起。(破除保持等待

在这里插入图片描述

生产者-消费者扩展问题

设有一个可以装A、B两种物品的仓库,其容量无限大,但要求仓库中A、B两种物品的数量满足下述不等式: A物品数量-B物品数量≤M,B物品数量-A物品数量<=N,其中M和N为正整数. 试用信号量和PV操作描述A、B两种物品的入库过程

  • A-B=M,B生产 A等待,设Sa=M,Sa不为0的时候可以生产A,Sa到0,则A被阻塞
  • B-A=N,A生产 B等待,设Sb=N,Sb不为0的时候可以生产B,Sb到0,则B被阻塞

⋆ \star 算法描述

semaphore Sa=M, Sb=N;
semaphore mutex=1;
process A() {
    while (1) {
        P(Sa);
        P(mutex);
        A产品入库;
        V(mutex);
        V(Sb);
    }
}

process B() {
    while (1) {
        P(Sb);
        P(mutex);
        B产品入库;
        V(mutex);
        V(Sa);  
    }
}

理发师问题

问题描述:理发店里有一位理发师、一把理发椅和n把供等候理发的顾客坐的椅子;如果没有顾客,理发师便在理发椅上睡觉,当一个顾客到来时,叫醒理发师;如果理发师正在理发时,又有顾客来到,则如果有空椅子可坐,就坐下来等待,否则就离开。

互斥资源:理发师、顾客、椅子

同步约束:访问椅子、顾客唤醒理发师、理发师唤醒下一个位等待顾客

算法描述

在这里插入图片描述

吸烟者问题

问题描述:三个吸烟者在一间房间内,还有一个香烟供应者。为了制造并抽掉香烟,每个吸烟者需要三样东西:烟草、纸和火柴。供应者有丰富的货物提供。三个吸烟者中,第一个有自己的烟草,第二个有自己的纸,第三个有自己的火柴。供应者将两样东西放在桌子上,允许一个吸烟者吸烟。当吸烟者完成吸烟后唤醒供应者,供应者再放两样东西(随机地)在桌面上,然后唤醒另一个吸烟者。

解题思路
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值