同步和互斥实验-吃水果问题、消费者问题
- 格式:doc
- 大小:137.50 KB
- 文档页数:7
《操作系统》实验报告生产者和消费者的问题一、实验目的1.掌握基本的同步与互斥的算法,理解基本的生产者与消费者的模型。
2.学习使用Windows 2000/XP中基本的同步对象,掌握相关的API的使用方法。
3.了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。
二、实验的内容及其要求1.实验内容以生产者/消费者模型为根据,在Windows 2000环境下创建一个控制台进程,在改进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求①学习并理解生产者/消费者模型及其同步/互斥规则②学习了解Windows同步对象及其特性③熟悉实验环境,掌握相关API的使用方法④设计程序,实现生产者/消费者进程(线程)的同步与互斥⑤提交实验报告三、实验的时间安排1.实验前,先到图书馆或上网百度了解有关生产者/消费者模型的相关知识,建立生产者/消费者模型的基本概念。
2.利用13周、15周、17周的上机时间编写和调试程序代码。
3.利用其他课余时间来分析实验的最终结果并完成相关的实验报告。
四、实验的环境1.硬件条件:普通计算机一台2.软件条件:①操作系统:Windows 2000/XP②开发语言:VC++本实验是在Windows 2000+VC6.0环境下实现的,利用Windows SDK提供的系统接口(API)完成程序的功能。
实验在Windows 下安装VC后进行,因为VC是一个集成开发环境,其中包含了Windows SDK所有工具和定义,所以安装了VC后就不用特意安装SDK了。
实验中所用的API(应用程序接口),是操作系统提供的用来进行应用程序设计的系统功能接口。
要使用这些API,需要包含对这些函数进行说明的SDK头文件,最常见的就是windows.h。
一些特殊的API调用还需要包含其他的头文件。
五、正文1.程序结构图:2.数据结构:(1)用一个整型数组Buffer_Critical来代表缓冲区。
实验、进程的同步与互斥——⽣产者消费者1. 1. 实验⽬的两个或两个以上的进程,不能同时进⼊关于同⼀组共享变量的临界区域,否则可能发⽣与时间有关的错误,这种现象被称作进程互斥。
对CPU的速度和数⽬不做出任何假设的前提下,并发进程互斥访问临界资源,是⼀个较好的解决⽅案。
另外,还需要解决异步环境下的进程同步问题。
所谓异步环境是指:相互合作的⼀组并发进程,其中每⼀个进程都以各⾃独⽴的、不可预知的速度向前推进;但它们⼜需要密切合作,以实现⼀个共同的任务,即彼此“知道”相互的存在和作⽤。
实验⽬的:分析进程争⽤资源的现象,学习解决进程同步与互斥的⽅法。
本实验属于设计型实验,实验者可根据⾃⾝情况选⽤合适的开发环境和程序架构。
1. 2. 实验原理信号量的PV操作与处理相关,P表⽰通过的意思,V表⽰释放的意思。
1962年,狄克斯特拉离开数学中⼼进⼊位于荷兰南部的艾恩德霍芬技术⼤学(Eindhoven Technical University)任数学教授。
在这⾥,他参加了X8计算机的开发,设计与实现了具有多道程序运⾏能⼒的操作系统——THE Multiprogramming System。
THE是艾恩德霍芬技术⼤学的荷兰⽂Tchnische Hoogeschool Eindhov –en的词头缩写。
狄克斯特拉在THE这个系统中所提出的⼀系统⽅法和技术奠定了计算机现代操作系统的基础,尤其是关于多层体系结构,顺序进程之间的同步和互斥机制这样⼀些重要的思想和概念都是狄克斯特拉在THE中⾸先提出并为以后的操作系统如UNIX等所采⽤的。
为了在单处理机的情况下确定进程(process)能否占有处理机,狄克斯特拉将每个进程分为“就绪”(ready)、“运⾏”(running)和“阻塞”(blocking)三个⼯作状态。
由于在任⼀时刻最多只有⼀个进程可以使⽤处理机,正占⽤着处理机的进程称为“运⾏”进程。
当某进程已具备了使⽤处理机的条件,⽽当前⼜没有处理机供其使⽤,则使该进程处于“就绪”状态。
桌子上有一只盘子,最多可容纳两个水果,每次只能放入或取出一个水果。
爸爸专向盘子放苹果(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。
实习一进程同步
一、实习内容
模拟进程同步。
二、实习目的
本实习要求学生理解进程同步的概念和进程同步技术——信号量机制。
三、实习题目
编写一个程序,模拟“吃水果问题”。
问题描述:桌上有一个盘子,每次只能放一个水果,爸爸专向盘中放苹果,妈妈专向盘中放橘子,儿子专等吃盘里的橘子,女儿专等吃盘里的苹果。
只要盘子空,爸爸妈妈可向盘中放水果,仅当盘中有自己需要的水果时,儿子或女儿可从中取出,请用信号量及PV操作模拟四人的同步关系。
提示:
(1)信号量和P、V(semwait&semsignal)操作原语自己定义,在保证该对原语原有意义的基础上,也可添加新内容(模拟的需要,结合提示(5)思考);
(2)4人分别是4个进程,每个进程的程序可由一个函数模拟;
其中,
进程名——作为进程的标识,自己定义。
状态——有两种状态,“就绪”和“阻塞”,初始状态都为“就绪”,用“R”表示。
当一个进程阻塞后,它的状态为“阻塞”,用“B”表示。
(3)当前执行哪个进程可由随机函数决定,若该进程当前是阻塞的,则打印“该进程阻塞”提示;否则,执行该进程程序;
(4)取、放水果的操作可用打印语句的方式替代;
(5)当一个阻塞态进程被唤醒成为就绪态,然后,再次被选中执行时,应从P原语的下一个语句开始执行。
这该怎么控制?想办法解决(结合提示(1)思考)。
注意:
信号量的设置和初值;
程序应有提示,界面友好!
用循环队列存阻塞队列和就绪队列。
进程同步互斥经典问题
进程同步与互斥是操作系统中的经典问题。
在多进程环境下,由于各个进程同时访问共享资源,会导致一系列问题,如数据不一致、死锁等。
因此,在进行多进程编程时,必须采取一些措施来保证进程之间的同步和互斥。
同步指的是在多个进程或线程之间,按照一定的顺序来执行程序流程,使得它们能够协同工作。
互斥指的是在多个进程或线程之间,对共享资源的访问进行限制,保证同一时间只有一个进程或线程能够进行访问,以防止数据的混乱和错误。
常见的进程同步和互斥问题包括生产者-消费者问题、读者-写者问题、哲学家就餐问题等。
这些问题都需要借助一些同步工具,如信号量、互斥锁、条件变量等来实现进程之间的同步和互斥。
在进行多进程编程时,需要充分理解进程同步和互斥的概念和原理,熟练掌握各种同步工具的使用方法,才能保证多进程程序的正确性和稳定性。
- 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问题的转换这是进程同步问题的模拟,可以把向盘子放或取水果的每一个过程可以转为一个进程的操作,这些进程是互斥的,同时也存在一定的同步关系。
C++11实现信号量(吃⽔果问题)c++11中有互斥和条件变量但是并没有信号量,但是利⽤互斥和条件变量很容易就能实现信号量。
1.信号量 信号量是⼀个整数 count,提供两个原⼦(atom,不可分割)操作:P 操作和 V 操作,或是说 wait 和 signal 操作。
P操作 (wait操作):count 减1;如果 count < 0 那么挂起执⾏线程;V操作 (signal操作):count 加1;如果 count <= 0 那么唤醒⼀个执⾏线程;2.信号量的实现 吃⽔果问题:桌⼦有⼀只盘⼦,只允许放⼀个⽔果,⽗亲专向盘⼦放苹果,母亲专向盘⼦放桔⼦⼉⼦专等吃盘⼦的桔⼦,⼥⼉专等吃盘⼦的苹果。
只要盘⼦为空,⽗亲或母亲就可以向盘⼦放⽔果,仅当盘⼦有⾃⼰需要的⽔果时,⼉⼦和⼥⼉可从盘⼦取出。
请给出四个⼈之间的同步关系,并⽤ pv操作实现四个⼈的正确活动的问题。
#include <iostream>#include <thread>#include <mutex>#include <condition_variable>using namespace std;class semaphore{public://初始化信号个数semaphore(int value = 1) :count(value) {}void P()//相当于信号P操作,申请⼀个信号{unique_lock<mutex> lck(mtk);if (--count < 0)//资源不⾜挂起线程cv.wait(lck);}void V()//相当于V操作,释放⼀个信号{unique_lock<mutex> lck(mtk);if (++count <= 0)//有线程挂起,唤醒⼀个cv.notify_one();}private:int count;mutex mtk;condition_variable cv;};//有苹果、橙⼦、盘⼦三种信号semaphore plate(1), apple(0), orange(0);void father(){while (true){//可⽤盘⼦减⼀plate.P();cout << "往盘中放⼀个苹果" << endl;//苹果加⼀apple.V();}}void mother(){while (true){//盘⼦减⼀plate.P();cout << "往盘中放⼀个橘⼦" << endl;//橙⼦加⼀orange.V();}}void son(){while (true){//苹果减⼀apple.P();cout << "⼉⼦吃苹果" << endl;//盘⼦加⼀plate.V();}}void daughter(){while (true){//橙⼦减⼀orange.P();cout << "⼥⼉吃橘⼦" << endl;//盘⼦加⼀plate.V();}}int main(){thread f(father), m(mother), s(son), d(daughter);f.join();m.join();s.join();d.join();system("pause");return0;}。
计算机操作系统实验报告题目三大经典问题之生产者与消费者问题一、课程设计的性质与任务1、加深对并发协作进程同步与互斥概念的理解。
通过编写程序实现进程同步和互斥,使学生掌握有关进程(线程)同步与互斥的原理,以及解决进程(线程)同步和互斥的算法,从而进一步巩固进程(线程)同步和互斥等有关的内容。
2、掌握进程和线程的概念,进程(线程)的控制原语或系统调用的使用。
3、了解Windows2000/XP中多线程的并发执行机制,线程间的同步和互斥。
学习使用Windows2000/XP中基本的同步对象,掌握相应的API函数。
4、培养学生能够独立进行知识综合,独立开发较大程序的能力。
5、培养提高学生软件开发能力和软件的调试技术。
6、培养学生开发大型程序的方法和相互合作的精神。
7、培养学生的创新意识。
8、培养学生的算法设计和算法分析能力。
9、培养学生对问题进行文字论述和文字表达的能力。
二、课程设计的内容及其要求在Windows?XP、Windows?2000等操作系统下,使用的VC、VB、Java或C等编程语言,采用进程(线程)同步和互斥的技术编写程序实现生产者消费者问题或哲学家进餐问题或读者-写者问题或自己设计一个简单进程(线程)同步和互斥的实际问题。
要求:(1)经调试后程序能够正常运行。
(2)采用多进程或多线程方式运行,体现了进程(线程)同步互斥的关系。
(3)程序界面美观。
三、实验原理本实验要求利用PV操作实现解决生产者——消费者问题中的同步问题。
此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。
四、实验原理图五、算法实现(1)有一个生产者线程ProduceThread,有1个消费者进程CustomerThread;缓冲区为shareList。
题目1:时间片轮转调度算法模拟要求:用实验方法模拟单处理机系统的进程调度,并采用时间片轮转调度算法作为进程调度算法。
具体任务:1、理解掌握进程调度实现所涉及到的主要问题:如何组织进程、如何实现处理机调度。
进程控制块的作用和结构,进程控制块的链表组织。
进程调度程序包含从进程就绪队列选择并摘取进程、给该进程分配处理机。
2、设计进程控制块相关数据结构,进程状态跃迁的相关模拟;3、实现时间片进程调度算法模拟程序设计、编码及调试。
题目2:静态优先级调度算法模拟要求:用实验方法模拟单处理机系统的进程调度,并采用静态优先级调度算法作为进程调度算法。
具体任务:1、理解掌握进程调度实现所涉及到的主要问题:如何组织进程、如何实现处理机调度。
进程控制块的作用和结构,进程控制块的链表组织。
进程调度程序包含从进程就绪队列选择并摘取进程、给该进程分配处理机。
2、设计进程控制块相关数据结构,进程状态跃迁的相关模拟;3、实现静态优先级调度算法模拟程序设计、编码及调试。
题目3:最短剩余时间优先(动态优先)调度算法模拟要求:用实验方法模拟单处理机系统的进程调度,并采用最短剩余时间优先调度算法作为进程调度算法。
具体任务:1、理解掌握进程调度实现所涉及到的主要问题:如何组织进程、如何实现处理机调度。
进程控制块的作用和结构,进程控制块的链表组织。
进程调度程序包含从进程就绪队列选择并摘取进程、给该进程分配处理机。
2、设计进程控制块相关数据结构,进程状态跃迁的相关模拟;3、实现最短剩余时间优先调度算法模拟程序设计、编码及调试。
题目4 作业调度设计1、目的本实验的目的是通过模拟作业调度算法的设计加深对作业管理基本原理的理解。
2、内容⑴在后备作业队列中,输入5个作业各自运行所需要的时间及存储空间。
①按先来先服务的原则进行调度,输出作业调度的顺序及等待的时间。
②按最短作业(即运行时间最短)优先的原则进行调度,输出作业调度的顺序及等待时间。
③按最小作业(即存储空间最小)优先的原则进行调度,输出作业调度的顺序及等待的时间。
实验3 报告源程序1/**作者:wwj时间:2012/4/12功能:实现吃水果问题**题目内容:桌子有一只盘子,只允许放一个水果,父亲专向盘子放苹果,母亲专向盘子放桔子儿子专等吃盘子的桔子,女儿专等吃盘子的苹果。
只要盘子为空,父亲或母亲就可以向盘子放水果,仅当盘子有自己需要的水果时,儿子和女儿可从盘子取出。
请给出四个人之间的同步关系,并用pv操作实现四个人的正确活动的问题。
****题目分析:父亲和女儿是相互制约的,父亲进程执行完即往盘中放入苹果后,女儿进程才能执行即吃苹果,是同步关系;母亲和儿子是相互制约的,母亲进程执行完即往盘中放入桔子,儿子进程才能执行即吃桔子,也是同步关系而父亲和母亲这两个进程不能同时进行,是互斥关系;****/#include<windows.h>#include<iostream>using namespace std;//声明句柄HANDLE EmptyPlate;HANDLE Apple;HANDLE orange;HANDLE fatherThread;HANDLE motherThread;HANDLE sonThread;HANDLE daughterThread;//线程函数声明DWORD WINAPI father(LPVOID IpParameter);DWORD WINAPI mother(LPVOID IpParameter);DWORD WINAPI daughter(LPVOID IpParameter);DWORD WINAPI son(LPVOID IpParameter);int main(){//创建信号量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;}//父亲线程函数DWORD WINAPI father(LPVOID IpParameter){for(int i = 0; i < 5; ++i){WaitForSingleObject(EmptyPlate, INFINITE); // P操作// 开始临界区cout << "\nFather往盘中放一个水果\n";// 结束临界区ReleaseSemaphore(Apple, 1, NULL); // V操作}return 0;}//母亲线程函数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;}//女儿线程函数DWORD WINAPI 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;//声明全局变量int i=0,j=0; //i和j分别指向缓冲区int buffer[n]; //缓冲池int ItemP=0; //用来存放生产的产品int ItemC=0; //用来存放消费的产品//声明句柄HANDLE mutex; //缓冲池信号量HANDLE empty; //空缓冲区信号量HANDLE full; //满缓冲区信号量HANDLE pThread; //producer线程句柄HANDLE cThread; //consumer线程句柄//声明进程函数DWORD WINAPI producer(LPVOID IpParameter);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;}程序运行截图如下:运行结果分析:从运行结果来看,整个市场运作有两种状态,一种状态是生产着连续生产两个产品,每生产一个产品后,立马把产品产品放入缓冲区,接着消费者消费产品;另一种状态是消费者先把缓冲区里面的产品消费,然后生产者把已经生产的产品放入缓冲区里;生产者和消费者即存在同步关系,又存在互斥关系,只是相对而言的,对于缓冲区来说,当缓冲区满的时候,只能由消费者消费产品,接着生产者才能把产品放入缓冲区;当缓冲区为空时,只能由生产者生产产品并把产品放入缓冲区,接着消费者才能消费产品;这两种关系都属于同步关系;对于缓冲池来说,缓冲池只有一个,生产者和消费者只能有一个使用它,并且他们不存在时序关系,到底是谁先使用,只能靠市场的调度和控制。