操作系统知识(第二章)3

参考视频:王道计算机考研 操作系统_哔哩哔哩_bilibili


目录

第二章 进程管理3

三、进程互斥

1. 并发进程

2.进程互斥 

3.进程互斥的软件实现方法

3.1 单标志法

3.2  双标志先检查法

3.3 双标志后检查法

3.4 Peterson算法

4.进程互斥的硬件实现方法

4.1 中断屏蔽方法

4.2 Test_And_Set指令

4.3 Swap指令

四、进程同步

1.信号量机制

1.1 整型信号量

 1.2 记录型信号量

1.3 信号量机制实现进程互斥

 1.4 信号量机制实现进程同步

1.5 信号量机制实现前驱关系

 2.经典进程同步问题1——生产者/消费者问题

附加:多生产者-多消费者

3.经典进程同步问题2——吸烟者问题

4.经典进程同步问题3——读者/写者问题

4.经典进程同步问题4——哲学家进餐问题


第二章 进程管理3

三、进程互斥

1. 并发进程

(1)前驱图

(2)顺序程序及其特性

内部顺序性:对于一个进程来说,它的所有指令是按序执行的。【指令顺序执行,颠倒顺序,含义不一样】

顺序程序特性:①连续性;②封闭性:不受其它程序及外界环境影响;③可再现性:结果与推进速度无关。

(3)并发程序及其特性

外部并发性:指多个程序之间的并发性。【程序之间并发执行】

并发程序的特性:①间断性:程序交叉执行;②非封闭性:一个进程的运行环境可以被其它进程改变;③不可再现性:由于交叉的随机性以及非封闭性,重新运行的程序不一定能重现上一次的结果。

(4)程序并发执行的条件

在间断性、非封闭性的条件下,保持可再现性。

2.进程互斥 

没有互斥:在终端1上判断x>=1成立后,若被中断了,则此时x还未执行x-1,x依然为1;此时,终端2上来了借书,判断x>=1依然成立;之后两者并发向下走,最终会出现 x = -1 的错误。

原因就在于 ①进程交叉执行;②存在共享变量x

互斥:多个进程不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误。

进程互斥的实现:

【空闲让进】进展性:临界区空闲时允许一个进程进入

【忙则等待】互斥性:一次只允许一个进程进入关于同一组公共变量的临界区,其他进程等待

【有限等待】:一个进程在等待有限个进程离开临界区后可获得进入临界区的机会

【让权等待】:进程不能进入临界区,就应立即释放处理器,防止忙式等待

临界区 / 临界段:访问临界资源。

进入区和退出区:负责实现互斥。

3.进程互斥的软件实现方法

3.1 单标志法

进程在访问完后交出权限。

若一直轮到P0执行,P1的while一直循环,当P0结束时,turn = 1,P1中跳出循环,轮到P1执行。

缺点:对于临界区,一定按照P0→P1→P0→P1→......轮流访问。首次允许进入临界区的进程是P0,若P0不想进入临界区,就会一直不访问临界区,那么即使临界区空闲,也不会允许P1访问,违背“空闲让进”原则(进展性)。

3.2  双标志先检查法

进程先检查其他进程是否想要进入临界区,没有则自己进入。

按照①⑤②⑥③⑦...执行,P0和P1将会同时访问临界区但是只能允许一个进程访问临界区,所以违背“忙则等待”原则。

【因为在①和②的空隙时间中会发生进程切换⑤,①②若能一气呵成则解决问题】

3.3 双标志后检查法

上一个是先检查后上锁,标志后检查是先上锁后检查。

 按照①⑤②⑥...执行,P0和P1都无法进入临界区。虽解决“忙则等待”问题,但又违背“空闲让进”和“有限等待”原则进程长时间无法访问临界资源而产生“饥饿”现象

3.4 Peterson算法

一、表示自己想要进入临界区的愿望;二、主动谦让对方先使用临界区;三、检测对方是否想使用

 Peterson解决了进程互斥问题,遵循“空闲让进”、“忙则等待”、“有限等待”三个原则,但是仍然未遵循“让权等待”的原则

4.进程互斥的硬件实现方法

4.1 中断屏蔽方法

进程访问临界区之前关中断,访问完后开中断。

优点:简单、高效。

缺点:不适用于多处理机,因为关中断关的只是一个处理机,另一个处理机依然可以中断;而且不适用于用户进程,只适用于操作系统内核进程。

4.2 Test_And_Set指令

TestAndSetLock(TSL)指令,此指令用硬件实现的,执行过程中不允许被中断。

C语言描述的逻辑:

 TSL指令将“上锁”与“检查”两个操作用硬件的方式变成原子操作。

优点:实现简单,不用检查是否有逻辑漏洞;而且适用于多处理机环境。

缺点:不满足“让权等待”原则,暂时无法进入临界区的进程依然会占用CPU并循环执行TSL指令,从而导致“忙式等待”

4.3 Swap指令

Exchange(XCHG)指令,硬件实现,不被中断。

C语言描述的逻辑:

 逻辑上看Swap与TSL并无太大区别。old初始为true,交换old与lock的值:若lock为false,说明没上锁,交换后上锁并使 old变为false 且 lock变为true,即跳出循环并上锁;若lock为true,说明已上锁,交换后old依然为ture,继续循环。

优点:实现简单;适用多处理机。

缺点:不满足“让权等待”原则,“忙式等待”

四、进程同步

1.信号量机制

 操作系统提供一对原语来对信号量进行操作,从而实现进程互斥、进程同步。信号量可以是一个用来表示系统中某种资源的数量。

wait(S) 原语和signal(S) 原语,常简称为P、V操作

1.1 整型信号量

用一整数型变量作为信号量,表示系统资源的数量。

★存在的问题:资源不足的情况下,wait检测一直占用处理机,整型信号量不满足“让权等待”,会发生“忙等”

 1.2 记录型信号量

执行wait消耗资源★资源不够(value--<0)时进程应调用block原语自我阻塞(运行态→阻塞态。 P0到P3都执行完wait后value的绝对值恰好为等待资源的进程数,即等待队列里的进程数。

【因为会自我阻塞,自动放弃处理机,遵循“让权等待”原则,不会出现“忙等”】

★在value++后依然存在 value<= 0时,执行signal原语释放相关资源,即唤醒等待队列队头进程阻塞态→就绪态

1.3 信号量机制实现进程互斥

① 分析并发程序的关键活动,划定临界区;

② 设置互斥信号量 mutex,初值为1;(注:对于不同临界资源需要设置不同互斥信号量)

③临界区之前执行P(mutex),临界区之后执行V(mutex),P、V操作成对出现。

 1.4 信号量机制实现进程同步

① 分析实现“同步”的地方,即需保证代码按照正确的顺序执行;

② 设置同步信号量S,初始为0;

③ “前操作”之后执行V(S);“后操作”之前执行P(S)。

 此时需先执行完“代码1、代码2”这些“前操作”,才能去执行“代码4、代码5、代码6”这些“后操作”。

若先执行P1到V(S)操作S++后S=1,再执行到P2的P(S)操作时,有可用资源不会阻塞P2进程,会继续执行代码4及以下。

若先执行P2在P(S)处会由于S--到S=-1,无可用资源,而使P2执行block原语阻塞起来只有执行到V(S)时发现S++为S=0,由于有进程在该信号对应的阻塞队列中,因此才会在V操作中执行wakeup原语,唤醒P2进程,再继续执行代码4。

即保证代码4一定是在代码2之后执行的。 

1.5 信号量机制实现前驱关系

结合上一节前驱图。

 2.经典进程同步问题1——生产者/消费者问题

生产者与消费者共享一个初始为空、大小为n的缓冲区。

缓冲区没满,生产者放产品,否则等待;缓冲区不空,消费者取产品,否则等待。

多个进程放入缓冲区的同一位置时,数据会被覆盖,因此各进程必须要互斥地访问缓冲区。

PV操作题目分析:

1.关系分析。几个进程,同步、互斥关系。

2.整理思路。确定操作流程P、V的大致顺序。【生产者消耗缓冲区(P1)生产一个产品(V2),消费者消耗一个产品(P2)释放一个缓冲区(V1)】

3.设置需要的信号量,①互斥访问缓冲区;②生产者放产品之前判断缓冲区是否满;③消费者取产品之前判断缓冲区是否空(互斥信号量mutex = 1,同步信号量empty = n,同步信号量full = 0)

若互斥的P操作处于同步的P操作之前(此时缓冲区已满),就可能会形成生产者执行完P(mutex)操作之后等待消费者释放缓冲区,而消费者在等待生产者执行V(mutex)释放临界资源的访问,因此形成“死锁”


附加:多生产者-多消费者

1️⃣关系分析。4类进程。

盘子需要互斥访问(互斥关系);父亲放🍎后女儿才能取🍎(同步关系);母亲放🍊后儿子才能取🍊(同步关系);只有盘子为空母亲或父亲才能放水果(同步关系)

2️⃣整理思路。确定P、V。互斥:临界区前后PV操作。同步:前V后P

互斥信号量:互斥访问盘子 mutex=1

同步信号量:apple=0;orange=0;plate=1

在访问临界区的前后要对mutex进行PV操作,切记两个P操作不能颠倒,不然死锁。

 若没有互斥信号量mutex,在盘子plate=1时(即缓冲区大小为1时)依然有可能实现进程对盘子的互斥访问。但是当plate > 1时就会出错,数据就有可能受到覆盖,丢失之前的信息。


3.经典进程同步问题2——吸烟者问题

4.经典进程同步问题3——读者/写者问题

读者并不会改变数据,因此多个读进程同时访问共享数据时不会产生副作用;而若某个写进程与多个读进程同时访问,将可能导致数据不一致的错误。因此要求:

① 允许多个读者同时读;② 只允许一个写者写;③ 写者写完前不准其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。

1️⃣关系分析。写进程、读进程。互斥:写进程与写进程、写进程与读进程。

2️⃣整理思路。设置互斥信号量rw,在写者之间互斥,读者和写者也互斥,因此读者访问前后也要对rw进行PV操作,但是读者不会更改数据,多个读者之间不需要互斥也能同时访问共享文件。

如何使读-读可以同时进行?(核心思想)

改进:最先进入的R进程执行P,最后离开的R进程执行V;其中需要count用于记录读者的数量。

这里的 count 对于读者来讲是一个共享变量,假如P2在P1还未进行count++时就开始,那么P2会在P(rw)处阻塞,P1和P2没有实现同时进行,因此,需要设置一个互斥信号量mutex

semaphore mutex = 1;//用于保证对count变量的互斥访问

问题:若读者源源不断,count不归0,写进程就会一直阻塞,写者就会被饿死。

策略:一旦有写者等待,新读者就要等待,在正在读的读者都结束后,写者进入。

设置一个新的互斥信号量 w=1。

① 读者R1在执行完V(w)后,读者R2也可以顺利执行完PV操作进行读文件【多个读者可同时】;

② 写者W1在完成P(w)后其他写者就会被阻塞直到W1执行V(w)【只有一个写者工作】;

③ 在写者写文件时由于为执行V(w),新来的读者会被阻塞在P(w)【写完前不准读】;

④ 读者正在读文件时,由于P(rw)已执行,在读完之前无法对rw “解锁”,因此写进程就会被阻塞在P(rw)处,又因为读进程中将w“上锁”,故新到的读者将阻塞在P(w)。最终,只有当前读者全部完成读文件后执行V(rw)才能继续写文件,而也只有写完后执行V(w),新的读者才能开始读文件。

4.经典进程同步问题4——哲学家进餐问题

五个哲学家,左右各一支筷子,每个哲学家需要获得两个临界资源才能开始吃饭。

1️⃣关系分析。五个哲学家进程,每个哲学家与左右邻居对其中间筷子的访问是互斥关系。

2️⃣整理思路。分配资源不当会造成每个哲学家都有一根筷子却都不肯放,形成“死锁”。即:

3️⃣信号量设置。定义互斥信号量数组 chopstick[5] = {1,1,1,1,1}用于实现对5根筷子的互斥访问。

核心问题是如何避免死锁。

方法:仅当一个哲学家左右两支筷子都可用时才允许抓起筷子。

保证至少有一个哲学家成功获得两个筷子,在进餐期间,其他哲学家进程都会阻塞(一个阻塞在拿左P(chopstick[ i ]) 或 拿右P(chopstick[(i+1)%5],其他三个阻塞在P(mutex)。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值