您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 操作系统课程设计“生产者-消费者”问题
《操作系统》课程设计题目:“生产者-消费者”问题学院:信息工程学院专业:计算机科学与技术班级:计科1302姓名:施胜飞指导老师:徐向英2016年1月15日操作系统课程设计-“生产者消费者”问题第1页共13页1目录一、课程设计目标………………………………………………………2二、课题内容…………………………………………………………21.实验目的………………………………………………………22、实验环境………………………………………………………23、实验要求………………………………………………………2三、设计思路…………………………………………………………31.信号量的设置……………………………………………………32.系统结构…………………………………………………………43.程序流程图………………………………………………………54.PV操作代码……………………………………………………6四、源代码……………………………………………………………7五、运行与测试……………………………………………………10六、心得体会………………………………………………………12操作系统课程设计-“生产者消费者”问题第2页共13页2一、课程设计目标学习SystemV的进程间通信机制,使用信号量和共享内存实现经典进程同步问题“生产者-消费者”问题。具体要求:1.创建信号量集,实现同步互斥信号量。2.创建共享内存,模拟存放产品的公共缓冲池。3.创建并发进程,实现进程对共享缓冲池的并发操作。二、课题内容1.实验目的(1)掌握基本的同步互斥算法,理解生产者和消费者同步的问题模型。(2)了解linux中多线程的并发执行机制,线程间的同步和互斥。2、实验环境:C/C++语言编译器3、实验要求(1)创建生产者和消费者线程在linux环境下,创建一个控制台进程,在此进程中创建n个线程来模拟生产者或者消费者。这些线程的信息由本程序定义的“测试用例文件”中予以指定。(2)生产和消费的规则在按照上述要求创建线程进行相应的读写操作时,还需要符合以下要求:①共享缓冲区存在空闲空间时,生产者即可使用共享缓冲区。②从上边的测试数据文件例子可以看出,某一生产者生产一个产品后,可能不止一个消费者,或者一个消费者多次地请求消费该产品。此时,只有当所有的消费需求都被满足以后,该产品所在的共享缓冲区才可以被释放,并作为空闲空间允许新的生产者使用。③每个消费者线程的各个消费需求之间存在先后顺序。例上述测试用例文件包含一行信息“5C3l24”,可知这代表一个消费者线程,该线程请求消费1,2,4号生产者线程生产的产品。而这种消费是有严格顺序的,消费1号线程产品的请求得到满足后才能继续往下请求2号生产者线程的产品。操作系统课程设计-“生产者消费者”问题第3页共13页3④要求在每个线程发出读写操作申请、开始读写操作和结束读写操作时分别显示提示信息。(3)相关基础知识本实验所使用的生产者和消费者模型具有如下特点:本实验的多个缓冲区不是环形循环的,也不要求按顺序访问。生产者可以把产品放到目前某一个空缓冲区中。消费者只消费指定生产者的产品。在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。本实验在为生产者分配缓冲区时各生产者间必须互斥,此后各个生产者的具体生产活动可以并发。而消费者之间只有在对同一产品进行消费时才需要互斥,同时它们在消费过程结束时需要判断该消费对象是否已经消费完毕并清除该产品。linux用来实现同步和互斥的实体。在linux中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex)、临界段(CriticalSection)等。使用这些对象都分为三个步骤,一是创建或者初始化:接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。这些同步对象在一个线程中创建,在其他线程中都可以使用,从而实现同步互斥。三、设计思路1.信号量的设置生产者进程与消费者进程是经典的同步互斥关系。系统创建两类进程:proceducer()和consumer(),分别用来描述生产者和消费者的行为。生产者与消费者问题是指若干进程通过循环缓冲池区交换数据。如下图所示,生产者进程不断向循环缓冲池区中写入数据(即生产数据),而消费者进程不断从循环缓冲池区中读出数据(即消费数据)。循环缓冲池共有N个缓冲区,缓冲区可以暂存一个产品,任何时刻只能有一个进程课对循环缓冲池进行操作。所有生产者和消费者要协调工作,以完成数据的交换。只要有空缓冲区,生产者就可以把产品送入缓冲区;只要有满缓冲区,消费者就可以从缓冲区中取走物品。为了解决生产者和消费者问题,应该设置信号量和变量如下:操作系统课程设计-“生产者消费者”问题第4页共13页4full:满缓冲区资源信号量,初值为0;empty:空缓冲区资源信号量,初值为n;in:生产者指针,初值均为0;out:消费者指针,均为0;mutex:缓冲区操作的互斥信号量,初值为12.系统结构PCB*readyhead=NULL,*readytail=NULL;//就绪队列——链表结构PCB*consumerhead=NULL,*consumertail=NULL;//消费者队列PCB*producerhead=NULL,*producertail=NULL;//生产者队列processproc()---给PCB分配内存,产生相应的的进程Pempty()---如果缓冲区满,该进程进入生产者等待队列;linkqueue(exe,&producertail);//把就绪队列里的进程放入生产者队列的尾部执行顺序:Main()---empty---in---full---out---finish当缓冲池为空时,生产者生产产品in缓冲池in=in+1当缓冲池为满时,消费者消费产品out缓冲池out=out+13.程序流程图操作系统课程设计-“生产者消费者”问题第5页共13页5图一生产者流程结构生产者线程开始资源信号量P操作互斥信号量P操作生产一个产品把产品送入缓冲区互斥信号量V操作资源信号量V操作等待队列中有消费者线程等待队列中有消费者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的消费者线程唤醒对头的消费者线程生产者线程结束YYNN操作系统课程设计-“生产者消费者”问题第6页共13页6图二消费者流程结构4.PV操作代码semaphoreempty=n;semaphorefull=0;semaphoremutex=1;messagebuffer[n];intin=0;intout=0;voidmain()消费者线程开始资源信号量P操作互斥信号量P操作从缓冲区取出一个产品消费一个产品互斥信号量V操作资源信号量V操作等待队列中有生产者线程等待队列中有生产者线程线程自我阻塞添加到等待队列线程自我阻塞添加到等待队列未通过未通过通过通过唤醒对头的生产者线程唤醒对头的生产者线程消费者线程结束YYNN操作系统课程设计-“生产者消费者”问题第7页共13页7{parbegin(proceducer(),consumer());}voidproceducer(){do{prodeceanewmeddage;P(empty);P(mutex);sendanewmessagetobuffer[in];in=(in+1)%n;V(mutex);V(full);}while(true);}voidconsumer(){do{P(full);P(mutex);getamessagefrombuffer[out];out=(out+1)%n;V(mutex);V(empty);comsumeamessage;}while(true);}四、源代码#includewindows.h#includeiostream.h#includemath.h#definerandom(rand()*10000)/RAND_MAX//定义一个随机函数来生产产品,并且使两个顾产品间的时间少于10秒intlongwaiting(0);//正在等待的产品的数目intbuffer;//空位的总数目charempty;//缓冲区空charfull;//缓冲区满intcount(0);//产品的号码数intfinish(0);//生产完毕的产品数目DWORDa;voidproceduce()操作系统课程设计-“生产者消费者”问题第8页共13页8{Sleep(10000);cout缓冲区已空!endl;//生产者生产产品函数,用时10秒}voidgetconsum(){Sleep(10001);//产品被生产的函数,为了合理区分生产产品cout第finish个产品被消费,取出endl;}HANDLEMutex=CreateMutex(NULL,FALSE,Mutex);//用来实现进程的互斥HANDLEproceducer=CreateSemaphore(NULL,1,1,proceducer);//定义信号量来进行线程间的同步HANDLEconsumer=CreateSemaphore(NULL,0,3,consum);DWORDWINAPIconsum(LPVOIDpParm2)//消费的线程{WaitForSingleObject(Mutex,INFINITE);//p(mutex)来进行互斥操作count++;//生产的是第几个产品cout第count个产品生产了endl;if(waitingbuffer)//如果缓冲池还有空位{if(waiting!=0){cout此时有waiting+1个产品等待消费endl;}elsecout没有产品在等待endl;//输出有多少人在等待waiting++;cout还有buffer-waiting个空位endl;cout有空区,产品已经进入endl;ReleaseSemaphore(consum,1,NULL);//v(consumer)ResumeThread(consum);//唤醒生产者进程ReleaseMutex(Mutex);//释放互斥量,以便其他线程使用WaitForSingleObject(proceducer,INFINITE);//等待生产getconsum();//消费并取走}else{cout缓冲区已满,第count个产品暂停生产endl;//没有空位,生产者不再生产ReleaseMutex(Mutex);}return0;}操作系统课程设计-“生产者消费者”问题第9页共13页9DWORDWINAPIproceducers(LPVOIDpParm1)//生产者的线程{while(true)//一直执行{WaitForSingleObject(consum,INFINITE);//p(customers),等待产品WaitForSingleObject(Mutex,INFINITE);//等待互斥量waiting--;//等待的产品数减一ReleaseSemaphore(proceducer,1,NULL);//释放信号量ResumeThread(proceducer);//唤醒消费进程ReleaseMutex(Mutex);//v(mutex);proceduce();//生产finish++;//消费的产品数加1}return0;}intmain(intargc,char*argv[]){cout请输入缓冲区空位的总数目:;cinbuffer;cout缓冲区共有buffer个空位endl;//设置缓冲区空位数目cout缓冲区空生产产品吗?Y/Nendl;//缓冲区是否空cinempty;while(empty!='y'){coutendl********对不
本文标题:操作系统课程设计“生产者-消费者”问题
链接地址:https://www.777doc.com/doc-2381488 .html