进程同步与互斥
- 格式:docx
- 大小:1.80 MB
- 文档页数:13
进程之间同步和互斥的区别和联系
1.同步是指多个进程之间按照一定的顺序执行,互斥是指多个进程之间不能同时访问共享资源。
2. 同步是为了保证进程之间执行顺序的正确性,互斥是为了避免多个进程同时访问共享资源导致数据不一致。
3. 同步机制可以通过信号量、事件、条件变量等方式实现,互斥机制通常使用互斥锁来实现。
联系:
1. 在多进程环境中,同步和互斥是相辅相成的,两者都是为了保证程序的正确性和安全性。
2. 互斥是同步的一种特殊形式,它是为了保证同步进行而采取的措施。
3. 同步和互斥都需要协调多个进程之间的关系,从而达到正确、高效地完成任务的目的。
总之,同步和互斥是操作系统中两个重要的概念,它们的区别在于同步是为了保证执行顺序的正确性,互斥是为了避免多个进程同时访问共享资源导致数据不一致,但是它们在多进程环境中都是相辅相成的。
- 1 -。
同步机制和互斥机制同步机制是指多个进程或线程在执行过程中,为了协调彼此的操作,按照一定的规则来进行协作,从而避免冲突和数据不一致的问题。
而互斥机制是同步机制的一种实现方式,通过互斥锁来保护共享资源,确保只有一个进程或线程可以访问改资源,其他进程或线程需要等待。
同步机制的作用主要是保持多线程或多进程之间的有序性,确保数据的可靠性和一致性。
在多线程或多进程的情况下,由于资源的共享,很容易出现数据竞争的问题,例如多个线程同时对同一变量进行修改,就有可能导致数据的不一致性和错误的结果。
同步机制通过引入一些规则和机制,来确保各个线程或进程之间按照一定的次序进行访问和操作,从而避免冲突和错误。
互斥机制是同步机制的一种实现方式,主要通过互斥锁来保护共享资源。
互斥锁是一种特殊的标志,只有获得了该标志的进程或线程才能访问共享资源,其他未获得该标志的进程或线程需要等待。
当一个进程或线程获得互斥锁后,其他进程或线程就无法获得该锁,只能等待,直到该进程或线程释放互斥锁。
互斥锁的引入可以防止多个进程或线程同时对共享资源进行修改,保证了数据的一致性。
同步机制和互斥机制是操作系统中非常重要的概念,对于并发编程和资源共享有着重要的作用。
在实际应用中,同步机制和互斥机制常常同时使用,实现对共享资源的保护和管理。
在多线程编程中,同步机制和互斥机制能够帮助我们避免一些典型的问题,比如竞态条件和死锁问题。
竞态条件指的是多个线程在同一时间同时访问某一共享资源,由于执行顺序的不确定性,导致的结果不确定性。
使用同步机制和互斥机制可以确保只有一个线程在同一时间访问共享资源,避免了竞态条件的发生。
而死锁问题指的是多个进程或线程因为相互之间循环等待资源而无法继续执行的情况。
同步机制和互斥机制可以通过合理的资源分配和管理,避免死锁的发生。
在实际编程中,同步机制和互斥机制有多种实现方式。
常用的实现方式包括信号量、互斥锁、条件变量等。
信号量是一种计数器,用于控制多个进程之间的同步和互斥。
详解进程同步与互斥机制⽬录⼀、什么是进程同步⼆、什么是进程互斥三、常见的进程同步与互斥机制⼀、什么是进程同步在多道批处理系统中,多个进程是可以并发执⾏的,但由于系统的资源有限,进程的执⾏不是⼀贯到底的,⽽是⾛⾛停停,以不可预知的速度向前推进,这就是进程的异步性。
那么,进程的异步性会带来什么问题呢?举个例⼦,如果有 A、B 两个进程分别负责读和写数据的操作,这两个线程是相互合作、相互依赖的。
那么写数据应该发⽣在读数据之前。
⽽实际上,由于异步性的存在,可能会发⽣先读后写的情况,⽽此时由于缓冲区还没有被写⼊数据,读进程 A 没有数据可读,因此读进程 A 被阻塞。
进程同步(synchronization)就是⽤来解决这个问题的。
从上⾯的例⼦我们能看出,⼀个进程的执⾏可能影响到另⼀个进程的执⾏,所谓进程同步就是指协调这些完成某个共同任务的并发线程,在某些位置上指定线程的先后执⾏次序、传递信号或消息。
再举个⽣活中的进程同步的例⼦,你想要喝热⽔,于是你打了⼀壶⽔开始烧,在这壶⽔烧开之前,你只能⼀直等着,⽔烧开之后⽔壶⾃然会发⽣响声提醒你来喝⽔,于是你就可以喝⽔了。
就是说⽔烧开这个事情必须发⽣在你喝⽔之前。
注意不要把进程同步和进程调度搞混了:进程调度是为了最⼤程度的利⽤ CPU 资源,选⽤合适的算法调度就绪队列中的进程。
进程同步是为了协调⼀些进程以完成某个任务,⽐如读和写,你肯定先写后读,不能先读后写吧,这就是进程同步做的事情了,指定这些进程的先后执⾏次序使得某个任务能够顺利完成。
⼆、什么是进程互斥同样的,也是因为进程的并发性,并发执⾏的线程不可避免地需要共享⼀些系统资源,⽐如内存、打印机、摄像头等。
举个例⼦:我们去学校打印店打印论⽂,你按下了 WPS 的 “打印” 选项,于是打印机开始⼯作。
你的论⽂打印到⼀半时,另⼀位同学按下了 Word 的 “打印” 按钮,开始打印他⾃⼰的论⽂。
想象⼀下如果两个进程可以随意的、并发的共享打印机资源,会发⽣什么情况?显然,两个进程并发运⾏,导致打印机设备交替的收到 WPS 和 Word 两个进程发来的打印请求,结果两篇论⽂的内容混杂在⼀起了。
第2章进程管理“练习与思考”解答1.基本概念和术语进程、进程互斥、进程同步、临界资源、临界区、死锁进程是程序在并发环境中的执行过程。
进程互斥:各个进程彼此不知道对方的存在,逻辑上没有关系,由于竞争同一资源(如打印机、文件等)而发生相互制约。
进程同步:各个进程不知对方的名字,但通过对某些对象(如I/O缓冲区)的共同存取来协同完成一项任务。
临界资源:一次仅允许一个进程使用的资源。
临界区:在每个进程中访问临界资源的那段程序。
死锁是指在一个进程集合中的每个进程都在等待仅由该集合中的另一个进程才能引发的事件而无限期地僵持下去的局面。
2.基本原理和技术(1)在操作系统中为什么要引入进程概念?它与程序的区别和联系是什么?在操作系统中,由于多道程序并发执行时共享系统资源,共同决定这些资源的状态,因此系统中各程序在执行过程中就出现了相互制约的新关系,程序的执行出现“走走停停”的新状态。
这些都是在程序的动态过程中发生的。
用程序这个静态概念已不能如实反映程序并发执行过程中的这些特征。
为此,人们引入“进程”这一概念来描述程序动态执行过程的性质。
进程与程序的主要区别是:·进程是动态的;程序是静态的。
·进程有独立性,能并发执行;程序不能并发执行。
·二者无一一对应关系。
·进程异步运行,会相互制约;程序不具备此特征。
但进程与程序又有密切的联系:进程不能脱离具体程序而虚设,程序规定了相应进程所要完成的动作。
(2)进程的基本状态有哪几种?通常在操作系统中,进程至少要有三种基本状态。
这三种基本状态是:运行态、就绪态和阻塞态(或等待态)。
(3)用如图3-23所示的进程状态转换图能够说明有关处理机管理的大量内容。
试回答:①什么事件引起每次显著的状态变迁?②下述状态变迁因果关系能否发生?为什么?(A)2→1 (B)3→2 (C)4→1图3-23 进程状态转换图①就绪→运行:CPU空闲,就绪态进程被调度程序选中。
实验一进程的同步与互斥一、实验目的(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的法。
(4)了解Windows对进程管理的支持。
二、实验类型观察/分析型。
三、预习内容预习进程管理有关理论和VC++对进程管理的支持, 包括进程的基本操作和经典的进程同步与互斥问题。
四、实验要求本实验通过学习和分析三个简单的Windows 线程编程编写一个简单的生产者/消费者问题实例程序。
利用(1)和(2)中的Windows 进程和线程创建法实现一个简单的读者,写者程序,读者将1~10 十个数字依次填入临界资源区gData,当且仅当gData 被读者消费后,写者才可以写入下一个数。
五、实验代码#include "windows.h"#include <conio.h>#include <stdio.h>#include <math.h>const int writerNum = 1;const int readerNum = 1;int gData = 0;bool continu = true;HANDLE hmutex;HANDLE hfullsemaphore;HANDLE hemptysemaphore;DWORD WINAPI reader(LPVOID lppara){while(continu){WaitForSingleObject(hemptysemaphore,INFINITE);WaitForSingleObject(hmutex,INFINITE);if(gData >= 11){continu = false;break;}Sleep(100);printf("readers gets data:%d\n", gData);printf("\n");ReleaseMutex(hmutex);ReleaseSemaphore(hfullsemaphore,1,NULL);}return NULL;}DWORD WINAPI writer(LPVOID lppara){while(continu){WaitForSingleObject(hfullsemaphore,INFINITE);WaitForSingleObject(hmutex,INFINITE);if(gData >= 10){continu = false;break;}Sleep(100);gData++;printf("writer gets data:%d\n", gData);printf("\n");ReleaseMutex(hmutex);ReleaseSemaphore(hemptysemaphore,1,NULL);}return NULL;}int main(){hmutex = CreateMutex(NULL,false,NULL);hfullsemaphore = CreateSemaphore(NULL,1,1,NULL);hemptysemaphore = CreateSemaphore(NULL,0,1,NULL);DWORD readerdata;DWORD writerdata;for (int i=0;i<writerNum;i++){if(CreateThread(NULL,0,writer,NULL,0,&writerdata)==NULL) return -1;}for (int j=0;j<readerNum;j++){if(CreateThread(NULL,0,reader,NULL,0,&readerdata)==NULL) return -1;}printf("Program ends successfully\n");return 0;}。
信号量实现进程互斥、同步、前驱关系信号量的值=这种资源的剩余数量(如果信号量的值⼩于0,说明此时有进程在等待这种资源)P(s)——申请⼀个资源,如果资源不够就阻塞等待V(S)——释放⼀个资源S,如果有进程在等待该资源,则唤醒⼀个进程。
1,信号量机制实现进程互斥(1)分析并发进程的关键活动,划定临界区(如:对临界资源打印机的访问就应放在临界区)(2)设置互斥信号量mutex,初值为1(3)在进⼊区P(mutex)——申请资源(4)在退出区V(mutex)——释放资源注意:对不同的临界资源需要设置不同的互斥信号量,p ,v操作必须成对出现。
缺少P(mutex)就不能保证临界资源的互斥访问,缺少V(mutex)会导致资源永不被释放,等待进程永不被唤醒。
/*记录型信号量的定义*/typedef struct{int value;struct process *L;}semaphore;/*信号量机制实现互斥*/semaphore mutex=1;p1(){...p(mutex);临界区代码...v(mutex);...}p2(){...p(mutex);临界区代码...v(mutex);...} 2,信号量实现进程同步进程同步:要让个并发进程按要求有序地推进。
p1(){代码1;代码2;代码3;}p2(){代码4;代码5;代码6;} ⽐如,p1,p2并发执⾏,由于存在异步性,因此⼆者交替推进的次序是不确定的。
若p2的代码4要基于p1的代码1和代码2的运⾏结果才能执⾏,那么我们就必须保证代码4⼀定是在代码2 之后才会执⾏。
这就是进程同步问题,让本来异步并发的进程互相配合,有序推进。
⽤信号量实现进程同步:(1)分析什么地⽅需要实现“同步关系”,即必须保证“⼀前⼀后”执⾏的两个操作(或两句代码)(2)设置同步信号量S,初始为0(3)在“前操作”之后执⾏V(S)(4)在后操作之前执⾏P(s)/*信号量机制实现同步*/semaphore S=0;//初始化同步信号量,初始值为0P1(){ P2(){代码1; P(s);代码2;代码4;V(s);//释放资源代码5;代码3;代码6;} } 若先执⾏到V(s)操作,则S++后S=1.之后当执⾏到P(s)操作时,由于s=1,表⽰有可⽤资源,会执⾏S--,S的值变回0,P2进程不会执⾏block原语,⽽是继续往下执⾏代码4.若先执⾏到P(s)操作,由于S=0,S--后S=-1,表⽰此时没有可⽤资源,因此P操作中会执⾏block原语,主动请求阻塞。
用P,V操作实现进程的同步与互斥摘要:进程的同步与互斥是操作系统中的重要问题。
通过P,V操作可以实现进程的同步与互斥。
本论文从P,V操作的原理入手,详细介绍了P,V操作在进程中的应用,以及它们对进程同步和互斥的作用。
通过本文的阐述,读者可以深入理解操作系统中P,V操作的实现原理及其在进程中的应用。
关键词:P,V操作;进程同步;进程互斥正文:1.引言进程的同步与互斥是操作系统中的重要问题。
同步是指在多进程环境下,控制进程之间相互合作的过程,互斥则是指在同一时间,只允许一个进程访问共享资源的过程。
为了实现进程的同步与互斥,操作系统中通常使用P,V操作。
2.P,V操作原理P,V操作是一种原子操作,它们可以保证在多进程环境下的资源访问的同步和互斥。
P操作用于请求共享资源,如果资源已被其他进程占用,那么当前进程就会被阻塞,等待资源释放;V操作用于释放共享资源,如果有其他进程正在等待该资源,那么就会唤醒其中一个进程继续执行。
3.P,V操作在进程中的应用在进程中,P,V操作主要用于实现进程之间的同步与互斥。
在同步方面,可以通过P操作等待其他进程执行完毕才继续执行;在互斥方面,可以通过P操作占用共享资源,在使用完毕后通过V操作释放资源。
4.P,V操作对进程同步和互斥的作用P,V操作对进程同步和互斥的作用十分重要。
在同步方面,P操作可以协调多个进程的执行顺序,使得它们按照一定的规则执行;在互斥方面,P操作可以保证同一时间只有一个进程占用共享资源,有效避免了资源冲突问题。
5.总结通过P,V操作可以实现进程的同步与互斥。
本文详细介绍了P,V操作的原理及其在进程中的应用,以及它们对进程同步和互斥的作用。
实践证明,P,V操作是一种有效的实现进程同步与互斥的方法。
6. P,V操作的局限性虽然P,V操作能够解决进程同步与互斥问题,但是它们也存在一些局限性。
首先,P,V操作采用了忙等待的方式,需要不断地检测是否可以进行操作,这会占用CPU资源。
学生实验报告姓名:年级专业班级学号成绩#define N 1 //N定义为临界资源!printf("请输入三个进程:\n"); //初始状态为:临界资源处于空闲状态!loop:scanf("%d %d %d",&a,&b,&c); //输入的进程名为:a,b,c!进程名输入的先后代表进程的访问顺序!if(a==N) //判断进程a是否占据临界资源!若a==N,表明a访问临界资源!{printf("a=%d\n",a); //a正在访问临界资源!printf("b=0,c=0\n"); //b,c不能进入自己的临界区,需等待a释放临界资源!printf(“临界资源正在被进程a访问,进程b,c必须等待.\n”);}else if(b==N){printf("b=%d\n",b); //b正在访问临界资源!printf("a=0,c=0\n"); //a,c不能进入自己的临界区,需等待b释放临界资源!printf(“临界资源正在被进程b访问,进程a,c必须等待.\n”);}5.编译链接所编写的程序,在编译正确的情况下执行程序.6.记录程序执行的结果(如下图所示).注意:初始状态为:临界资源处于空闲状20 10年12 月16 日【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)1.进程a,b,c分别访问临界资源时程序执行的结果如下.(a) (b) (c)2.该程序初始化N为临界资源,根据输入a,b,c,的值是否等于N来判断进程分别是否进入自己的临界区。
当a=N 表明进程a正在访问临界资源。
此时程序执行的输出为:a=1,b=c=0表示进程b,c不能进入自己的临界区。
3.该程序能较好地体现程序并发执行时的一种制约关系-互斥,但不能较好的反映进程的同步关系,所以该算法有待改进,用以同时实现进程的同步和互斥。
进程同步与互斥进程的PV操作在操作系统中,P、V操作是进程管理中的难点。
这是1968年荷兰人Dijkstra 给出的一种解决并发进程间互斥和同步关系的通用方法。
1. P、V操作的意义定义了信号量及其上的P操作和V操作,来实现并发进程间的同步和互斥,甚至可以用来管理资源的分配。
P、V操作因交换的信息量少,属于进程的低级通信。
2. 什么是信号量?信号量(semaphore)是由一个值和一个指针构成的数据结构。
值为整型变量,表示信息量的值;指针指向进程控制块(PCB)队列的队头,表示等待该信号量的下一个进程。
如下图所示。
信号量的一般结构及PCB队列信号量的值与相应资源的使用情况有关。
当它的值大于0时,表示当前可用资源的数量;当它的值小于0时,其绝对值表示等待使用该资源的进程个数。
注意,信号量的初值不能为负,且其值只能由P、V操作来改变。
3. P、V操作的含义P、V操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量S进行操作,具体定义如下:P(S):①将信号量S的值减1,即S=S-1;②如果S≥0,则该进程继续执行;否则该进程状态置为阻塞状态,进程PCB 排入信号量PCB队列末尾,放弃CPU,等待V操作的执行。
V(S):①将信号量S的值加1,即S=S+1;②如果S≤0,释放信号量队列中第一个PCB所对应的进程,将进程状态由阻塞态改为就绪态。
执行V操作的进程继续执行。
一般来说,信号量S≥0时,S表示可用资源的数量。
执行一次P操作意味着请求分配一个单位资源,因此S的值减1;当S<0时,表示已经没有可用资源,请求者必须等待别的进程释放该类资源,它才能运行下去。
而执行一个V操作意味着释放一个单位资源,因此S的值加1;若S≤0,表示有某些进程正在等待该资源,因此要唤醒一个阻塞状态的进程,使之成为就绪状态。
4. 利用信号量和P、V操作实现进程互斥一般地,n个进程利用信号量和P、V操作实现进程互斥的一般模型如下:进程P1进程P2……进程Pn…… …… ……P(S); P(S); P(S);临界区;临界区;临界区;V(S); V(S); V(S);…… …… …… ……其中S是互斥信号量,初值为1。
使用P、V操作实现进程互斥时应该注意的问题是:(1)每个程序中,用户实现互斥的P、V操作必须成对出现,先做P操作,进临界区,后做V操作,出临界区。
若有多个分支,要认真检查P、V操作的成对性。
(2)P、V操作应分别紧靠临界区的头尾部,临界区的代码应尽可能短,不能有死循环。
(3)互斥信号量的初值一般为1。
由于用于互斥的信号量sem与所有的并发进程有关,所以称之为公有信号量。
公有信号量的值反映了公有资源的数量。
只要把临界区置于P(sem)和V(sem)之间,即可实现进程间的互斥。
就象火车中的每节车厢只有一个卫生间,该车厢的所有旅客共享这个公有资源:卫生间,所以旅客间必须互斥进入卫生间,只要把卫生间放在P(sem)和V(sem)之间,就可以到达互斥的效果。
以下例子说明进程的互斥实现。
例1生产围棋的工人不小心把相等数量的黑子和白子混装载一个箱子里,现要用自动分拣系统把黑子和白子分开,该系统由两个并发执行的进程组成,功能如下:(1)进程A专门拣黑子,进程B专门拣白子;(2)每个进程每次只拣一个子,当一个进程在拣子时不允许另一个进程去拣子;分析:第一步:确定进程间的关系。
由功能(2)可知进程之间是互斥的关系。
第二步:确定信号量及其值。
由于进程A和进程B要互斥进入箱子去拣棋子,箱子是两个进程的公有资源,所以设置一个信号量s,其值取决于公有资源的数目,由于箱子只有一个,s的初值就设为1。
实现:begins:semaphore;s:=1;cobeginprocess AbeginL1: P(s);拣黑子;V(s);goto L1;end;process BbeginL2:P(s);拣白子;V(s);goto L2;end;coend;end;判断进程间是否互斥,关键是看进程间是否共享某一公有资源,一个公有资源与一个信号量相对应。
确定信号量的值是一个关键点,它代表了可用资源实体数。
如下实例:例2某车站售票厅,任何时刻最多可容纳20名购票者进入,当售票厅中少于20名购票者时,厅外的购票者可立即进入,否则需要在外面等待。
每个购票者可看成一个进程。
分析:第一步:确定进程间的关系。
售票厅是各进程共享的公有资源,当售票厅中多于20名购票者时,厅外的购票者需要在外面等待。
所以进程间是互斥的关系。
第二步:确定信号量及其值。
只有一个公有资源:售票厅,所以设置一个信号量s。
售票厅最多容纳20个进程,即可用资源实体数为20,s的初值就设为20。
实现:begins:semaphore;s:=20;cobeginprocess PI(I=1,2,……)begin P(s);进入售票厅;购票;退出;V(s);end;coend当购票者进入售票厅前要执行P(s)操作,执行后若s大于或等于零,说明售票厅的人数还未满可进入。
执行后若s小于零,则说明售票厅的人数已满不能进入。
这个实现中同时最多允许20个进程进入售票厅购票,其余进程只能等待。
5. 利用信号量和P、V操作实现进程同步P、V操作是典型的进程同步机制之一。
用一个信号量与一个消息联系起来,当信号量的值为0时,表示期望的消息尚未产生;当信号量的值为非0时,表示期望的消息已经存在。
用P、V操作实现进程同步时,调用P操作测试消息是否到达,调用V操作来发送消息。
使用P、V操作实现进程同步时应该注意的问题是:(1)分析进程间的制约关系,确定信号量种类。
在保持进程间有正确的同步关系情况下,哪个进程应先执行,哪些进程后执行,彼此间通过什么信号量进行协调,从而明确要设置哪些信号量。
(2)信号量的初值与相应资源的数量有关,也与P、V操作在程序代码中出现的位置有关。
(3)同一信号量的P、V操作要成对出现,但它们分别在不同的进程代码中。
与进程互斥不同,进程同步时的信号量只与制约进程及被制约进程有关而不是与整组并发进程有关,所以称该信号量为私有信号量。
利用PV原语实现进程同步的方法是:首先判断进程间的关系为同步的,且为各并发进程设置私有信号量,然后为私有信号量赋初值,最后利用PV原语和私有信号量规定各进程的执行顺序。
下面我们将例1增添一个条件,使其成为进程间是同步的。
例3在例1的基础之上再添加一个功能:(3)当一个进程拣了一个棋子(黑子或白子)以后,必让另一个进程拣一个棋子(黑子或白子)。
分析:第一步:确定进程间的关系。
由功能(1)(2)(3)可知,进程间的关系为同步关系。
第二步:确定信号量及其值。
进程A和B共享箱子这个公有资源,但规定两个进程必须轮流去取不同色的棋子,因而相互间要互通消息。
对于进程A可设置一个私有信号量s1,该私有信号量用于判断进程A是否能去拣黑子,初值为1。
对于进程B同样设置一个私有信号量s2,该私有信号量用于判断进程B 是否能去拣白子,初值为0。
当然你也可以设置s1初值为0,s2初值为1。
实现:begins1,s2:semaphore;s1:=1;s2:=0;cobeginprocess AbeginL1: P(s1);拣黑子;V(s2);goto L1;end;process BbeginL2:P(s2);拣白子;V(s1);goto L2;end;coend;end;另外一个问题就是P原语是不是一定在V原语的前面?回答是否定的。
下面看一个例子。
例4设在公共汽车上,司机和售票员的活动分别是:司机:启动车辆,正常行车,到站停车。
售票员:上乘客,关车门,售票,开车门,下乘客。
用PV操作对其控制。
分析:第一步:确定进程间的关系。
司机到站停车后,售票员方可工作。
同样,售票员关车门后,司机才能工作。
所以司机与售票员之间是一种同步关系。
第二步:确定信号量及其值。
由于司机与售票员之间要互通消息,司机进程设置一个私有信号量run,用于判断司机能否进行工作,初值为0。
售票员进程设置一个私有信号量stop,用于判断是否停车,售票员是否能够开车门,初值为0。
实现:begin stop ,run:semaphorestop:=0;run:=0;cobegindriver: begin消费者进程 while(True){ P(full); 从Buffer 取出一个产品; V(empty); 消费该产品; } L1: P(run);启动车辆;正常行车;到站停车;V(stop);goto L1;end;conductor:beginL2:上乘客;关车门;V(run);售票;P(stop);开车门;下乘客;goto L2;end;coend;end;用PV 操作还可以实现进程同步与互斥的混合问题,典型的如:多个生产者和多个消费者共享容量为n 的缓存区。
这个例子在很多书中都有介绍,在这里就不说了。
6. P 、V 操作举例【例1】生产者-消费者问题在多道程序环境下,进程同步是一个十分重要又令人感兴趣的问题,而生产者-消费者问题是其中一个有代表性的进程同步问题。
下面我们给出了各种情况下的生产者-消费者问题,深入地分析和透彻地理解这个例子,对于全面解决操作系统内的同步、互斥问题将有很大帮助。
(1)一个生产者,一个消费者,公用一个缓冲区(Buffer )。
empty ——表示缓冲区是否为空,初值为1。
full ——表示缓冲区中是否为满,初值为0。
生产者进程while(TRUE){生产一个产品;P(empty);产品送往Buffer;V(full);}(2)一个生产者,一个消费者,公用n 个环形缓冲区。
消费者进程 while(TRUE){ P(full); 从buffer (out )中取出产品; out=(out+1) mod n ; V(empty); 消费该产品; } 消费者进程 while(TRUE){ P(full); P(mutex2); 从buffer (out )中取出产品; out=(out+1) mod n ; V (mutex2); V(empty); 消费该产品; }定义两个同步信号量:empty ——表示缓冲区是否为空,初值为n 。
full ——表示缓冲区中是否为满,初值为0。
设缓冲区的编号为1~n -1,定义两个指针in 和out ,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。
生产者进程while(TRUE){生产一个产品;P(empty);产品送往buffer (in );in=(in+1) mod n ;V(full);}(3)一组生产者,一组消费者,公用n个环形缓冲区 在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。