目录
0.前言
1.同步与互斥问题总览
2.生产者-消费者问题
2.1 单生产者-单消费者-多资源
2.2 多生产者-多消费者-单资源
2.3 吸烟者问题(单生产者-多消费者-单资源)
2.4 和尚打水问题(多生产者-多消费者-多资源)
3.读写者问题
3.1 读者优先
3.2 写者优先
3.3 过桥问题(双读者)
0.前言
本系列文章旨在记录操作系统的知识点,可用于期末复习,笔者理解尚浅,文中不正之处静待批正。专题篇为大题常考题型,必须要重点把握。
1.同步与互斥问题总览
我们主要讨论通过信号量的PV操作来实现同步与互斥,本篇主要关注生产者-消费者问题及变体和读写者问题等。
对于互斥:
- 主要通过互斥锁mutex来实现,初值为1
- 不同的临界区资源要用不同的信号量
- 在临界区之前进行P操作,临界区之后进行V操作,必须成对出现
对于同步:
- 主要通过同步信号量来实现,初值为0
- 按照顺序来执行进程,先V后P
- 同步一定在互斥之前
2.生产者-消费者问题
2.1 单生产者-单消费者-多资源
互斥:由于缓冲区为n,所以需要用互斥锁来实现同一进程对缓冲区的互斥访问,先P后V
同步:生产者生成完后发出已满的信号,然后再由消费者消费;同时消费者消费完后,发出已空的信号,再由生产者生产。因此先V后P
2.2 多生产者-多消费者-单资源
分析:由于有多个生产者和消费者,因此每一个生产者消费者都有自己的信号量。生产者接收盘子为空的信号,然后争夺使用权,并生产自己的水果。而消费者接收自己需要的水果信号,消费完后发出盘子为空的信号。因为缓冲区大小为1,已经实现了互斥,所以也可以不需要互斥锁。
2.3 吸烟者问题(单生产者-多消费者-单资源)
分析:与2.2类似,吸烟者只需要等待自己所需的才材料的信号,而供应者需要轮流地提供材料。由于只有缓冲区可以视为1,因此也不需要互斥锁来维护缓冲区。
2.4 和尚打水问题(多生产者-多消费者-多资源)
初始化时:
sem empty = 10; //缓冲区大小,水缸还剩多少 sem full = 0; //实现同步 sem mutex1 = 1; //表示对井的互斥 sem mutex2 = 1; //表示对缸的互斥 sem count = 3; //桶的数量
分析:对于这种涉及变量较多的问题需要先理清执行过程,按照过程来书写。对于小和尚来说,先接收到水缸空了的信号,然后去拿桶,再去井中取水,取出水后需要将水倒入缸中,最后还桶并告诉老和尚水缸已满。对于老和尚来说,先接收到水缸已满的信号,然后去拿桶,再去缸中取水,最后还桶并告诉小和尚水缸空了。在整个过程中,需要对井、缸、桶实现互斥,保证只有一个进程在使用,然后通过空和满的信号来实现同步。要注意的是初始化时empty信号就等于缓冲区的大小。
3.读写者问题
问题分析:①写与读需要互斥;②写与写需要互斥;③读与读不需要互斥
3.1 读者优先
目前正在读,新的读会持续进入,写会饥饿
分析:如果有多个读进程,则第一个读进行上锁,后续的读可以连续进入,同时最后一个读进行解锁,保证了读者优先于写者。
3.2 写者优先
当有新的写存在,新的读不能进行读
分析:mutex1和mutex2实现读写进程对于自身的互斥。如果目前正在写,并且新的读和写同时到达,读写都会在semWait(writemutex)上等待,因此需要竞争进入,没有保证写优先。
分析:仿照读者优先,在第一个写进程到达时拿到读的互斥锁,则后续的写会阻塞在外面,当最后一个写执行完后再释放锁。但是如果当前正在读,并且同时来一个写和读,第一个写和所有新的读都会在semwait(readmutex)上等待,需要竞争,依然没有保证写优先。
(正解)分析:为了解决正在读情况下,新写和新读中新写无法优先的问题,让读先在z上排队,而写在readmutex排队,由于z的释放晚于readmutex,因此可以保证写优先。
有可能部分读者会认为z的引入是多余的,因此可以让readmutex位于mutex1里面,而mutex1就充当了z的作用,因此会写出下面的程序:
分析:如果进程的到达顺序是读-写-读,且第一个读正在readdata(),那么写进程会阻塞于semWait(writemutex),而第二个读会阻塞于semWait(readmutex)。此时就会发生死锁,因为第二个读已经拿到了mutex1,导致第一个读readdata()完成后会阻塞于semWait(mutex1)。
3.3 过桥问题(双读者)
问题一:有一座桥,东西走向,汽车可以从东往西走,也可以西往东走,桥上每次只允许朝一个方向走,请用信号量描述下列过程: 如果某一个方向的车占有桥,让这个方向的车优先过桥
分析:由于只有有一方的车占有桥就让这个方向的车优先通过,两个方向都不存在读与读的互斥,所以本题只存在读者,并且都在争夺对桥的使用权。其中mutex维护对于桥的互斥。
问题修改:让两个方向的车公平的过桥,即东西方向的车在同一个队列(信号量)上排队
分析:公平的过桥意思就是没有优先级,不存在某一方要让某一方,则只需要让两个方向的来车进行公平竞争即可。初始化queue=1
问题修改:在上述修改的基础上同时要满足如果east方向的车正在通行,又来一辆east方向的车,而第三辆是west方向的车,那么第二辆车可以在第一辆通行过程中加入
分析:与上一问稍微不同的是,上一问是一次只能通过一个车,且公平竞争,而这一问要求第一个竞争到桥的所有权的方向可以一直通车,而如果是1e,2w,3e的到达顺序,则会公平执行。因此只需要将释放queue信号的位置提前就可以实现。