复习回顾+思考:之前学习的这些进程互斥的解决方案分别存在哪些问题?
进程互斥的四种软件实现方式(单标志法、双标志先检查、双标志后检查、Peterson算法 )
进程互斥的三种硬件实现方式(中断屏蔽方法、TS/TSL指令 、Swap/XCHG指令 )
1.在双标志先检查法中,进入区的“检查”、“ 上锁”操作无法一气呵成,从而导致了两个进程有可能同时进入临界区的问题;
2.所有的解决方案都无法实现“让权等待”
信号量其实就是一个变量(可以是一个整数, 也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量,比如:系统中只有一台打印机,就可以设置一一个初值为1的信号量。
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥、进程同步。
原语是一种特殊的程序段,其执行只能-气呵成,不可被中断。原语是由关中断/开中断指令实现的。软件解决方案的主要问题是由“进入区的各种操作无法一气呵成”,因此如果能把进入区、退
出区的操作都用“原语”实现,使这些操作能“一气呵成”就能避免问题。
一对原语: wait(S) 原语和signal(S)原语,可以把原语理解为我们自己写的函数,函数名分别为wait和signal(译为:信号),括号里的信号量S其实就是函数调用时传入的一个参数。
wait、signal 原语常简称为P、V操作(来自荷兰语proberen和verhogen)。因此,做题的时候常把wait(S)、signal(S) 两个操作分别写为P(S)、V(S)
用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。Eg:某计算机系统中有一台打印机…
**与普通整数变量的区别:**对信号量的操作只有三种,即初始化、P操作、V操作
整型信号量的缺陷是存在“忙等”问题,因此人们又提出了“记录型信号量”,即用记录型数据结构表示的信号量。
注意:对不同的临界资源需要设置不同的互斥信号量。
P、V操作必须成对出现。
缺少P(mutex)就不能保证临界资源的互斥访问。缺少V(mutex)会导致资源永不被释放,等待进程永不被唤醒。
进程同步:要让各并发进程按要求有序地推进。
若先执行到V(S)操作,则S++后S=1。之后当执行到P(S)操作时,由于S=1,表示有可用资源,会执行S–, S的值变回0,
P2进程不会执行block原语,而是继续往下执行代码4。若先执行到P(S)操作,由于S=0,S-- 后S=-1,表示此时没有
可用资源,因此P操作中会执行block原语,主动请求阻塞。之后当执行完代码2,继而执行V(S)操作,S++, 使S变回0,
由于此时有进程在该信号量对应的阻塞队列中,因此会在V操作中执行wakeup原语,唤醒P2进程。这样P2就可以继续
执行代码4了
进程P1中有句代码S1,P2中有句代码S2…P6中有句代码S6。这些代码要求按如下前驱图所
示的顺序来执行:
其实每一对前驱关系都是一个进程同步问题(需要保证一前一后的操作)
因此,
系统中有一-组生产者进程和一-组消费者进程,生产者进程每次生产-一个产品放入缓冲区,消费者
进程每次从缓冲区中取出一一个产品并使用。(注: 这里的“产品”理解为某种数据)
生产者、消费者共享一个初始为空、大小为n的缓冲区。
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。缓冲区是临界资源,各进程必须互斥地访问。
桌子.上有一只盘子,每次只能向其中放入-一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放
橘子,儿子专等着吃盘子中的橘子,女儿专等着吃盘子中的苹果。只有盘子空时,爸爸或妈妈才
可向盘子中放-一个水果。仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出水果。
用PV操作实现.上述过程。
假设一个系统有三个抽烟者进程和一一个供应者进程。每个抽烟者不停地卷烟并抽掉它,但是要卷
起并抽掉一支烟, 抽烟者需要有三种材料:烟草、纸和胶水。三个抽烟者中,第- 一个拥有烟草、
第二个拥有纸、第三个拥有胶水。供应者进程无限地提供三种材料,供应者每次将两种材料放桌
子上,拥有剩”下那种材料的抽烟者卷一根烟并抽掉它, 并给供应者进程一一个信号告诉完成了,供
应者就会放另外两种材料再桌上,这个过程一直重复(让三个抽烟者轮流地抽烟)
有读者和写者两组并发进程,共享-一个文件,当两个或两个以上的读进程同时访问共享数据时不
会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致
数据不一致的错误。
因此要求:
①允许多个读者可以同时对文件执行读操作;
②只允许一个写者往文件中写信息;
③任一写者在完成写操作之前不允许其他读者或写者工作;
④写者执行写操作前,应让已有的读者和写者全部退出。
1.关系分析。找出题目中描述的各个进程,分析它们之间的同步、互斥关系。
2.整理思路。 根据各进程的操作流程确定P、 V操作的大致顺序
3. 设置信号量。设置需要的信号量,并根据题目条件确定信号量初值。 (互斥信号量初值- -般为1,
同步信号量的初始值要看对应资源的初始值是多少)
两类进程:写进程、读进程
互斥关系:写进程-写进程、写进程一读进程。读进程与读进程不存在互斥问题。
写者进程和任何进程都互斥,设置一个互斥信号量rw,在写者访问共享文件前后分别执行P、V操作。
读者进程和写者进程也要互斥,因此读者访问共享文件前后也要对rw执行P、V操作。
如果所有读者进程在访问共享文件之前都执行P(rw)操作,那么会导致各个读进程之间也无法同时
访问文件。Key:读者写者问题的核心思想一-怎么处理该问题呢?
一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子, 桌子的中间是一碗米饭。哲学
家们倾注毕生的精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿时,
才试图拿起左、右两根筷子(一根一-根地拿起)。如果筷子已在他人手,上,则需等待。饥饿的哲
学家只有同时拿起两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。
引入管程的目的无非就是要更方便地实现进程互斥和同步。
1.需要在管程中定义共享数据(如生产者消费者问题的缓冲区)
2.需要在管程中定义用于访问这些共享数据的“入口”- --其实就是一些函数(如生产者消费者
问题中,可以定义一个函数用于将产品放入缓冲区,再定义一个函数用于从缓冲区取出产品)
3.只有通过这些特定的“入口”才能访问共享数据
4.管程中有很多“入口”,但是每次只能开放其中一个“入口”,并且只能让一个进程或线程进
入(如生产者消费者问题中,各进程需要互斥地访问共享缓冲区。管程的这种特性即可保证一
个时间段内最多只会有一一个进程在访问缓冲区。注意:这种互斥特性是由编译器负责实现的,
程序员不用关心)
5.可在管程中设置条件变量及等待/唤醒操作以解决同步问题。可以让- 一个进程或线程在条件变量
.上等待(此时,该进程应先释放管程的使用权,也就是让出“入口”) ;可以通过唤醒操作将
等待在条件变量.上的进程或线程唤醒。
程序员可以用某种特殊的语法定义-一个管程(比如: monitor ProducerConsumer … end monitor;),
之后其他程序员就可以使用这个管程提供的特定“入口”很方便地使用实现进程同步/互斥了。
管程是一种特殊的软件模块,有这些部分组成:
1.局部于管程的共享数据结构说明;
2.对该数据结构进行操作的一组过程(函数);
3. 对局部于管程的共享数据设置初始值的语句;
4.管程有一个名字。
管程的基本特征:
1.局部于管程的数据只能被局部于管程的过程所访问;
2.一个进程只有通过调用管程内的过程才能进入管程访问共享数据;
3.每次仅允许一个进程在管程内执行某个内部过程。