同步和互斥实验吃水果问题消费者问题
放水果

桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。
爸爸专向盘子放苹果(apple),妈妈专向盘子放桔子(orange)。
两个儿子专等吃盘子中的桔子,两个女儿专等吃盘子中的苹果。
请用信号量来实现爸爸、妈妈、儿子、女儿之间的同步与互斥关系。
解:本题原型为生产者-消费者问题,只是由一种产品改为两种水果,所以将表示满缓冲区单元个数的一个信号量改为表示盘中苹果的个数和桔子个数的两个信号量,设置如下信号量:empty:记录允许向盘子中放入水果的个数,初值为2。
apple:盘子中已放入的苹果的个数,初值为0。
orange:盘子中已放入的桔子的个数,初值为0。
mutex:向盘子中取、放操作是一个互斥操作,也就是说盘子对于取、放水果而言是一个临界资源,为此设置一个信号量,其初值为1。
本题4个进程的同步与互斥活动的描述如下:Var mutex, empty, apple, orange:=1,2,0,0BeginFather:beginRepeatwait(empty); //盘中可放入的水果数wait(mutex); //申请向盘中取、放水果向盘中放苹果;signal(mutex); //允许向盘中取、放水果signal(apple); //递增盘中的苹果数endMother:beginRepeatwait (empty); //减少盘中可放入的水果数wait (mutex); //申请向盘中取、放水果向盘中放桔子;signal (mutex); //允许向盘中取、放水果signal (orange); //递增盘中的桔子数endDaughteri(i=1,2):begin //两女儿进程Repeatwait(apple); //减少盘中苹果数wait (mutex); //申请向盘中取、放水果取盘中苹果;signal (mutex); //允许向盘中取、放水果signal (empty); //递增盘中可放入的水果数endSonj(j=1,2):begin //两儿子进程Repeatwait (orange); //减少盘中桔子数wait (mutex); //申请向盘中取、放水果取盘中桔子;signal (mutex); //允许向盘中取、放水果signal (empty); //递增盘中可放入的水果数endend和尚取水:Var Semaphore:mutex1=1;mutex2=1;empty=10;full=0;pail=3; BeginparbeginGet() //小和尚取水Repeatwait(empty)wait(pail)wait(mutex1)从井中取水;signal (mutex1)wait(mutex2)将水倒入缸中;signal (mutex2) signal (full)signal (pail)parendparbeginUse() //老和尚喝水Repeatwait(full)wait(pail)wait(mutex2)从缸中取水signal (mutex2) ;signal (empty)喝水signal (pail) parend。
桌上有一空盘,最多允许存放一只水果

桌上有一空盘,最多允许存放一只水果.爸爸可向盘中放一个苹果或放一个桔子,儿子专问题描述:桌上有一空盘,最多允许存放一个水果。
爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。
试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。
问题分析及思路:1.这个话题就是生产者和消费者的扭曲,不是一个信号量就能解决的。
在这个问题中,父亲、儿子和女儿共用一个盘子,一次只能往盘子里放一个水果。
当盘子空了,父亲可以在盘子里放一个水果。
如果苹果放在采摘盘里,允许女儿吃,儿子要等。
如果橘子放在盘子里,儿子被允许吃,女儿必须等。
2.那么盘子就是一个缓冲(单缓冲),同一时间只能有一个人放和拿。
所以这个盘子是互斥的。
但是当盘子里有苹果,父亲不放的时候,儿子可以拿,女儿也一样。
所以应该有两个资源信号量:1个苹果和2个橙子3.根据题意分析,三个信号量的初始值应该是1 0 0,因为桌子上只能放一个水果。
开始的时候桌子是空的(所以可以放),所以苹果和橘子的初始资源是空的。
PV操作如下:int put=1,apple=0,orange=0;//定义同步信号量Father://父亲进程While(1){P(put);放一个苹果或者橘子;if(fruit==apple)V(apple);elseV(orange);}Daughter://女儿进程While(1){P(apple);拿一个苹果;V(put);吃苹果;}Son://儿子进程While(1){P(orange);拿一个桔子;V(put);吃桔子;}。
计算机操作系统(第三版)-复习题答案

操作系统第一章复习题一、选择题1、下列选项中,( D )不是操作系统关心的主要问题。
A 管理计算机裸机B 设计、提供用户程序与计算机硬件系统的界面。
C 管理计算机系统资源D 高级程序设计语言的编译器2、多道批处理系统的主要缺点是( C )。
A CPU利用率低B 不能并发执行C 缺少交互性D 以上都不是。
3、在操作系统中,( D )部分属于微内核。
A 输入/输出井的管理程序,及作业调度软件。
B 用户命令解释程序C 磁盘文件目录管理软件D 进程通信服务例程4、通常在分时系统中运行的作业称为( C )。
A 前台作业B 后台作业C 终端型作业D 批量型作业5、在下面的选项中,( A )不属于操作系统提供给用户的可用资源。
A 中断机制B 处理机C 存储器D I/O 设备6、操作系统在计算机系统中处于( B )的位置。
A 计算机硬件和软件之间B 计算机硬件和用户之间C 处理机和用户程序之间D 外部设备和处理机之间7、操作系统是对( C )进行管理的软件。
A 软件 B硬件 C计算机资源 D 应用程序8、操作系统中采用多道程序设计技术提高了CPU和外部设备的( A )。
A 利用率B 可靠性C 稳定性D 兼容性9、操作系统提供给程序员的接口是( B )。
A 进程B 系统调用C 库函数D B和C10、所谓( B )是指将一个以上的作业放入内存,并且同时处于运行状态,这些作业共享处理机的时间和外围设备等其他资源。
A 多重处理B 多道程序设计C 实时处理D 共行执行11、实时系统必须在( C )内处理完来自外部的事件。
A 响应时间B 周转时间C 规定时间D 调度时间12、在操作系统中,并发性是指若干事件( C )发生。
A 在同一时刻B 一定在不同时刻C 在某一时间间隔D 依次在不同时间间隔内13、订购机票系统处理各个终端的服务请求,处理后通过终端回答用户,所以它是一个( D )。
A 分时系统B 多道批处理系统C 计算机网络 D实时信息处理系统二、填空题1、操作系统两个最基本的特征是(并发)和(共享),两者之间互为存在条件。
进程同步模拟设计--吃水果问题

附件1:学号:012课程设计题目进程同步模拟设计--吃水果问题学院计算机科学与技术学院专业计算机科学与技术专业班级计算机姓名指导教师2011 年01 月19 日课程设计任务书学生:专业班级:指导教师:作单位:计算机科学与技术学院题目: 进程同步模拟设计——吃水果问题初始条件:1.预备容:阅读操作系统的进程管理章节容,对进程的同步和互斥,以及信号量机制度有深入的理解。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.模拟吃水果的同步模型:桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。
爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,两个儿子专门等待吃盘子中的橘子,两个女儿专门等吃盘子中的苹果。
2.设计报告容应说明:⑴需求分析;⑵功能设计(数据结构及模块说明);⑶开发平台及源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。
时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收、撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日进程同步模拟设计——吃水果问题1需求分析1.1吃水果问题的描述桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。
爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,两个儿子专门等待吃盘子中的橘子,两个女儿专门等吃盘子中的苹果。
1.2问题的转换这是进程同步问题的模拟,可以把向盘子放或取水果的每一个过程可以转为一个进程的操作,这些进程是互斥的,同时也存在一定的同步关系。
信号量地PV操作(例题)

???信号量的PV操作是如何定义的?试说明信号量的PV操作的物理意义。
参考答案:P(S):将信号量S减1,若结果大于或等于0,则该进程继续执行;若结果小于0,则该进程被阻塞,并将其插入到该信号量的等待队列中,然后转去调度另一进程。
V(S):将信号量S加1,若结果大于0,则该进程继续执行;若结果小于或等于0,则从该信号量的等待队列中移出一个进程,使其从阻塞状态变为就绪状态,并插入到就绪队列中,然后返回当前进程继续执行。
PV操作的物理含义:信号量S值的大小表示某类资源的数量。
当S>0时,其值表示当前可供分配的资源数目;当S<0时,其绝对值表示S信号量的等待队列中的进程数目。
每执行一次P操作,S值减1,表示请求分配一个资源,若S≥0,表示可以为进程分配资源,即允许进程进入其临界区;若S<0,表示已没有资源可供分配,申请资源的进程被阻塞,并插入S的等待队列中,S的绝对值表示等待队列中进程的数目,此时CPU将重新进行调度。
每执行一次V操作,S值加1,表示释放一个资源,若S>0,表示等待队列为空;若S≤0,则表示等待队列中有因申请不到相应资源而被阻塞的进程,于是唤醒其中一个进程,并将其插入就绪队列。
无论以上哪种情况,执行V操作的进程都可继续运行。
1、设公共汽车上,司机和售票员的活动分别是:司机的活动:启动车辆;正常行车;到站停车;售票员的活动:关车门;售票;开车门;在汽车不断地到站、停车、行驶过程中,这两个活动有什么同步关系?用P、V操作实现它们的同步。
设两个信号量S和C,初值为S=0;C=0;司机: L1:正常行车售票员: L2:售票到站停车 P(S)V(S)开车门P(C)关车门启动开车 V(C)GO TO L1 GO TO L22、请用PV操作实现他们之间的同步关系:(1)桌上一个盘子,只能放一只水果。
爸爸放苹果,妈妈放桔子,儿子只吃桔子,女儿只吃苹果。
(2)桌上一个盘子,只能放一只水果。
吃苹果问题

操作系统实验报告――吃苹果问题一.实验目的:1)对同步与互斥有更深体会2)了解多线程如何工作及其设计3)掌握多线程对应的API函数二.实验题目与要求:有父亲、儿子、女儿三人和一个盘子。
当盘子空时,父亲往盘中放水果(只有苹果和香蕉),每次随机放苹果或香蕉,儿子和女儿马上取该水果,但是儿子只从盘中拿苹果,女儿只从盘中拿香蕉。
请模拟这样的一个过程,其中父亲放水果20 次。
三.程序分析首先,父亲放一个苹果在盘,儿子马上取苹果这件事与父亲放一个香蕉,女儿马上取之这件事是互斥的。
即在程序中体现在:当父亲每次放水果之后马上唤醒儿子或女儿来取,当一个孩子还没有拿到水果之前,父亲不允许放水果,另外一个孩子也不许来破坏。
我们用“临界区”实现:父亲函数:……进入临界区放苹果或香蕉……儿子或女儿函数:……取苹果或香蕉退出临界区……另外,儿子和女儿在默默等待,只要父亲放了水果他们就拿。
程序中表现在:儿女见到盘子没有水果,就被阻塞,父亲每次放水果后唤醒阻塞的孩子函数。
我们分别用信息量Apple和Banana作为父亲唤醒儿女和儿女等待的途径。
四.程序实现(程序在Microsoft visual studio 8编译链接)#include<windows.h>#include<iostream>#include<stdlib.h>#include<time.h>using namespace std;CRITICAL_SECTION mmutex;//临界区互斥HANDLE Apple,Banana;int k = 0;//记录线程号DWORD WINAPI Son(LPVOID n)//儿子行为函数{int i = 1;HANDLE Apple;Apple = ::OpenSemaphore(MUTEX_ALL_ACCESS,false,(LPCWSTR)"apple");//打开一个命名为apple的信号量while(1){//Sleep(2000);::WaitForSingleObject(Apple,INFINITE);//等待父亲生产苹果cout<<"Son eats "<<i<<" apples"<<endl;LeaveCriticalSection(&mmutex);//离开临界区i++;}::CloseHandle(Apple);//退出线程return 0;}DWORD WINAPI Daughter(LPVOID n)//女儿行为函数{int i =1;HANDLE Banana;Banana = ::OpenSemaphore(MUTEX_ALL_ACCESS,false,(LPCWSTR)"banana");//打开一个命名为banana的信号量while(1){//Sleep(2000);::WaitForSingleObject(Banana,INFINITE);//等待父亲生产香蕉cout<<"Daughter eats "<<i<<" bananas"<<endl;LeaveCriticalSection(&mmutex);//离开临界区i++;}::CloseHandle(Banana);//退出线程return 0;}DWORD WINAPI Father(LPVOID n)//父亲行为函数{UINT fruit;EnterCriticalSection(&mmutex);//进入临界区//产生一个随机数srand(GetTickCount());fruit = rand()%2;if(fruit == 0){cout<<k+1<<" father produce an apple"<<endl;//放苹果::ReleaseSemaphore(Apple,1,NULL);//唤醒儿子吃苹果}else{cout<<k+1<<" father produce a banana"<<endl;//放香蕉::ReleaseSemaphore(Banana,1,NULL);//唤醒女儿吃香蕉}k = k+1;return 0;}int main(){Apple = ::CreateSemaphore(NULL,0,1,(LPCWSTR)"apple");//产生命名为apple的信号量Banana = ::CreateSemaphore(NULL,0,1,(LPCWSTR)"banana");//产生命名为banana的信号量InitializeCriticalSection(&mmutex);//给临界区初始化for (int j= 0 ; j < 20; j++){::CreateThread(NULL,0,Father,NULL,0,0);//创建父亲线程}::CreateThread(NULL,0,Son,NULL,0,0);//创建儿子线程::CreateThread(NULL,0,Daughter,NULL,0,0);//创建女儿线程Sleep(30000);//等待秒之后再结束main函数return 0;}五.程序结果六.实验心得1.在产生随机数的时候必须加上srand(GetTickCount())这个函数,否则每次系统都是产生同一个数,因此每次父亲总是生产苹果或者香蕉。
操作系统-吃水果问题

操作系统-吃水果问题操作系统-吃水果问题1、引言本文档描述了一个操作系统的模拟问题-吃水果问题。
该问题涉及到多个进程同时对有限数量的水果资源进行访问的情况。
我们将介绍该问题的背景、目标和关键概念。
2、背景吃水果问题模拟了现实生活中多个进程同时访问共享资源的情况。
在该问题中,不同的进程可以同时访问一定数量的水果资源。
然而,由于水果资源有限,进程必须遵守特定的规则以确保公平访问。
3、目标该问题的目标是设计一种算法,使得不同的进程能够共享有限的水果资源。
我们的目标是确保进程之间的公平访问,并通过合适的同步机制来避免产生竞争条件和死锁。
4、关键概念4.1 进程(Process)进程是计算机中正在运行的程序的实例。
在吃水果问题中,每个进程代表一个人,这些人需要同时访问共享的水果资源。
4.2 共享资源(Shared Resource)共享资源是多个进程可能同时访问的资源。
在吃水果问题中,水果资源是共享资源,被多个进程同时竞争。
4.3 同步机制(Synchronization Mechanism)同步机制用于控制多个进程对共享资源的访问。
在吃水果问题中,我们需要设计一种同步机制来确保进程之间的公平访问和避免竞争条件。
5、解决方案5.1 问题分析首先,我们需要确定问题的规模和要求。
包括进程数量、水果资源数量以及对公平访问的要求等。
5.2 同步机制设计我们可以采用多种同步机制来解决吃水果问题,例如互斥锁、条件变量等。
在设计同步机制时,需要考虑到公平性、死锁避免和性能等方面的因素。
5.3 算法实现根据设计的同步机制,我们需要实现相应的算法来解决吃水果问题。
这个算法应该能够正确地控制进程对资源的访问,并满足公平访问和避免死锁的要求。
6、测试与调试在实现算法之后,我们需要进行测试和调试来确保算法的正确性和性能。
包括编写测试用例、模拟并发情况和调整参数等。
7、结论通过本文档,我们介绍了操作系统中的吃水果问题,并提供了解决该问题的解决方案。
容斥原理最值问题

容斥原理最值问题嘿,朋友们!今天咱来聊聊容斥原理最值问题,这可真是个有意思的玩意儿啊!你说啥是容斥原理最值问题呢?咱打个比方哈,就好比你去参加一个大聚会,里面有喜欢吃苹果的人,有喜欢吃香蕉的人,还有既喜欢吃苹果又喜欢吃香蕉的人。
那怎么能知道最多有多少人喜欢吃这两种水果,或者最少有多少人喜欢呢?这就是容斥原理最值问题啦!咱想想啊,要是只知道喜欢苹果的有多少人,喜欢香蕉的有多少人,可直接把这俩数加起来,那肯定不对呀,因为里面有重复的部分呢,这时候就得用容斥原理来好好算算了。
那最值又是咋回事呢?就好比你想让喜欢吃水果的人最多或者最少,那可得好好琢磨琢磨条件,找到那个最极端的情况。
比如说,有一个班级,会唱歌的有 20 人,会跳舞的有 15 人,既会唱歌又会跳舞的有 5 人。
那这时候让你求既不会唱歌也不会跳舞的最多有多少人,你就得好好想想啦。
要是想让这个最多,那是不是得让会唱歌和会跳舞的人尽可能地重复呀,这样既不会唱歌也不会跳舞的人不就多了嘛!你说是不是这个理儿?再举个例子,有一堆水果,苹果有 10 个,香蕉有 8 个,橘子有 6 个,既喜欢苹果又喜欢香蕉的有 3 个,既喜欢苹果又喜欢橘子的有 2 个,既喜欢香蕉又喜欢橘子的有 1 个,三种都喜欢的有 1 个。
那这时候让你求喜欢至少一种水果的最少有多少人,这可得好好动动脑筋了。
是不是得让那些重复的部分尽可能地少呀,这样喜欢至少一种水果的人不就最少了嘛!哎呀呀,这容斥原理最值问题是不是挺好玩的?就像解一个小谜题一样,得仔细琢磨条件,找到那个最关键的点。
有时候你可能会觉得有点绕,但别着急,慢慢来,多想想,肯定能搞明白的。
你想想,生活中不也经常会遇到这样的问题嘛。
比如说你组织一个活动,要知道最多能有多少人参加,或者最少需要准备多少东西,这不就和容斥原理最值问题差不多嘛!所以说呀,学会这个可有用啦!咱再回到学习上,遇到这种问题可别头疼,要把它当成一个挑战,一个让你变得更聪明的机会。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验3 报告源程序1/**作者:wwj时间:2012/4/12功能:实现吃水果问题**题目内容:桌子有一只盘子,只允许放一个水果,父亲专向盘子放苹果,母亲专向盘子放桔子儿子专等吃盘子的桔子,女儿专等吃盘子的苹果。
只要盘子为空,父亲或母亲就可以向盘子放水果,仅当盘子有自己需要的水果时,儿子和女儿可从盘子取出。
请给出四个人之间的同步关系,并用pv操作实现四个人的正确活动的问题。
****题目分析:父亲和女儿是相互制约的,父亲进程执行完即往盘中放入苹果后,女儿进程才能执行即吃苹果,是同步关系;母亲和儿子是相互制约的,母亲进程执行完即往盘中放入桔子,儿子进程才能执行即吃桔子,也是同步关系而父亲和母亲这两个进程不能同时进行,是互斥关系;****/#include〈windows.h>#include<iostream〉using namespace std;//声明句柄HANDLEEmptyPlate;HANDLEApple;HANDLE orange;HANDLE fatherThread;HANDLEmotherThread;HANDLE sonThread;HANDLEdaughterThread;//线程函数声明DWORD WINAPI father(LPVOID IpParameter);DWORD WINAPI mother(LPVOIDIpParameter);DWORD WINAPI daughter(LPVOID IpParameter);DWORD WINAPI son(LPVOID IpParameter);intmain(){//创建信号量EmptyPlate = CreateSemaphore(NULL,1,1,NULL); //盘子Apple = CreateSemaphore(NULL,0,1,NULL);//苹果ﻩorange = CreateSemaphore(NULL,0,1,NULL); //桔子ﻩ//创建线程fatherThread = CreateThread(NULL,0,father,NULL,0,NULL);ﻩmotherThread = CreateThread(NULL,0,mother,NULL,0,NULL);daughterThread = CreateThread(NULL,0,daughter,NULL,0,NULL);sonThread = CreateThread(NULL,0,son,NULL,0,NULL);ﻩ//等线程的结束WaitForSingleObject(fatherThread,INFINITE);ﻩWaitForSingleObject(motherThread,INFINITE);ﻩWaitForSingleObject(daughterThread,INFINITE);ﻩWaitForSingleObject(sonThread,INFINITE);ﻩ//关闭线程句柄CloseHandle(fatherThread);ﻩCloseHandle(motherThread);ﻩCloseHandle(daughterThread);ﻩCloseHandle(sonThread);//关闭信号量句柄ﻩCloseHandle(EmptyPlate);CloseHandle(Apple);CloseHandle(orange);ﻩreturn 0;}//父亲线程函数ﻩDWORDWINAPI father(LPVOID IpParameter)ﻩ{ﻩﻩfor(inti= 0;i〈 5; ++i){ﻩﻩWaitForSingleObject(EmptyPlate,INFINITE);ﻩ// P操作ﻩ// 开始临界区ﻩcout <〈”\nFather往盘中放一个水果\n";// 结束临界区ReleaseSemaphore(Apple, 1,NULL);ﻩ// V操作ﻩﻩ}ﻩﻩreturn0;ﻩ}ﻩ//母亲线程函数ﻩDWORD WINAPI mother(LPVOID IpParmeter){ﻩﻩfor(int i = 0;i 〈5; ++i){ﻩWaitForSingleObject(EmptyPlate,INFINITE);ﻩ// P操作ﻩ//开始临界区ﻩcout <<”\nMother往盘中放一个桔子\n";// 结束临界区ReleaseSemaphore(orange, 1, NULL);ﻩ// V操作ﻩ}ﻩreturn 0;}//女儿线程函数ﻩDWORDWINAPI daughter(LPVOID IpParameter){ﻩwhile(1)ﻩ{ﻩﻩWaitForSingleObject(Apple,INFINITE); //p操作ﻩcout<<”女儿吃苹果"<<endl;ReleaseSemaphore(EmptyPlate,1,NULL); //v操作ﻩﻩ}ﻩreturn 0;ﻩ}//儿子线程函数DWORD WINAPI son(LPVOID IpParameter)ﻩ{ﻩwhile(1)ﻩ{ﻩﻩWaitForSingleObject(orange,INFINITE); //p操作ﻩﻩcout<<"儿子吃苹果"<〈endl;ﻩﻩﻩReleaseSemaphore(EmptyPlate,1,NULL); //v操作ﻩ}ﻩreturn 0;}程序运行结果截图:运行结果分析:从运行结果可知父进程执行完后,女儿进程立即执行,这说明父进程跟女儿进程有时序关系,只有当父进程执行之后,女儿进程才会执行,女儿进程是父进程的子线程,他们具有同步关系,同理;母亲进程跟儿子进程,也是同步关系。
源程序2/**作者:wwj时间:2012/4/12功能:实现生产者和消费者正常活动题目内容:生产者-消费者问题,是指两组进程共享一个环形的缓冲区。
一组进程被称为生产者,另一组进程被称为消费者。
缓冲池是由若干个(程序假设为4个)大小相等的缓冲区组成的,每个缓冲区可以容纳一个产品。
生产者进程不断地将生产的产品放入缓冲池,消费者进程不断地将产品从缓冲池取出。
用PV操作实现生产者和消费者的正常活动的程序题目分析:在生产者-消费者问题中,既存在进程同步问题,也存在着临界区的互斥问题.当缓冲区都满时,表示供大于求,生产者停止生产,进入等待状态,同时唤醒消费者;当缓冲区都空时,表示供不应求,消费者停止消费,唤醒生产者。
这说明了,生产者和消费者存在同步关系.对于缓冲池,它显然是一个临界资源,所有的生产者和消费者都要使用它,而且都要改变它的状态,故对于缓冲池的操作必须是互斥的。
*/#include<Windows.h>#include<iostream〉using namespace std;const int n=4;//声明全局变量inti=0,j=0; //i和j分别指向缓冲区int buffer[n]; //缓冲池int ItemP=0;ﻩ//用来存放生产的产品intItemC=0;ﻩ//用来存放消费的产品//声明句柄HANDLE mutex;ﻩ//缓冲池信号量HANDLEempty; //空缓冲区信号量HANDLE full;ﻩ//满缓冲区信号量HANDLE pThread;ﻩ//producer线程句柄HANDLE cThread; //consumer线程句柄//声明进程函数DWORD WINAPI producer(LPVOIDIpParameter);DWORD WINAPI consumer(LPVOID IpParameter);int main(){//创建信号量mutex = CreateSemaphore(NULL,1,1,NULL);empty =CreateSemaphore(NULL,1,4,NULL);ﻩfull = CreateSemaphore(NULL,0,4,NULL);cout〈〈"市场运作开始。
.。
.”〈〈endl;ﻩ//创建线程pThread = CreateThread(NULL,0,producer,NULL,0,NULL);cThread = CreateThread(NULL,0,consumer,NULL,0,NULL);ﻩ//等待相应线程结束ﻩWaitForSingleObject(pThread,INFINITE);WaitForSingleObject(cThread,INFINITE);ﻩﻩ//关闭线程句柄CloseHandle(pThread);ﻩCloseHandle(cThread);ﻩ//关闭信号量句柄ﻩCloseHandle(mutex);ﻩCloseHandle(empty);CloseHandle(full);ﻩcout〈〈"整个市场运营结束.。
”<<endl;return 0;}//producer线程函数的定义DWORD WINAPI producer(LPVOID IpParameter)ﻩ{ﻩfor(int k=0;k〈5;k++){ﻩcout<<”\nproducer生产一个产品"<〈endl;ItemP=ItemP+1; ﻩ//增加一个产品ﻩﻩWaitForSingleObject(empty,INFINITE);//P操作ﻩﻩWaitForSingleObject(mutex,INFINITE);ﻩcout〈〈"\n把一个产品放入了一个空的缓冲区"<<endl;ﻩbuffer[i]=ItemP;ﻩ//将产品放入缓冲区ﻩﻩﻩi=(i+1)%n;ﻩﻩﻩﻩReleaseSemaphore(mutex,1,NULL);ﻩ//V操作ﻩﻩReleaseSemaphore(full,1,NULL);}ﻩreturn 0;}ﻩDWORD WINAPI consumer(LPVOID IpParameter){ﻩfor(int k=0;k<5;k++)ﻩ{ﻩWaitForSingleObject(full,INFINITE);ﻩ//P操作ﻩﻩﻩWaitForSingleObject(mutex,INFINITE);ﻩﻩﻩItemC=buffer[j];ﻩ//将缓冲区里的产品取出,放入消费产品里头ﻩj=(j+1)%n;ﻩﻩﻩﻩ//j指向下一个满的缓冲区ﻩﻩReleaseSemaphore(mutex,1,NULL);ﻩﻩ//V操作ﻩﻩReleaseSemaphore(empty,1,NULL);ﻩﻩcout<〈”\n消费者消费一个产品"<〈endl;ﻩﻩItemC=ItemC-1;ﻩ//消费一个产品}ﻩﻩreturn 0;ﻩ}程序运行截图如下:运行结果分析:从运行结果来看,整个市场运作有两种状态, 一种状态是生产着连续生产两个产品,每生产一个产品后,立马把产品产品放入缓冲区,接着消费者消费产品;另一种状态是消费者先把缓冲区里面的产品消费,然后生产者把已经生产的产品放入缓冲区里;生产者和消费者即存在同步关系,又存在互斥关系,只是相对而言的,对于缓冲区来说,当缓冲区满的时候,只能由消费者消费产品,接着生产者才能把产品放入缓冲区;当缓冲区为空时,只能由生产者生产产品并把产品放入缓冲区,接着消费者才能消费产品;这两种关系都属于同步关系;对于缓冲池来说,缓冲池只有一个,生产者和消费者只能有一个使用它,并且他们不存在时序关系,到底是谁先使用,只能靠市场的调度和控制。