大工19春《操作系统》大作业答案.docx
- 文档编号:29702231
- 上传时间:2023-07-26
- 格式:DOCX
- 页数:13
- 大小:75.59KB
大工19春《操作系统》大作业答案.docx
《大工19春《操作系统》大作业答案.docx》由会员分享,可在线阅读,更多相关《大工19春《操作系统》大作业答案.docx(13页珍藏版)》请在冰豆网上搜索。
大工19春《操作系统》大作业答案
.
网络教育学院
《操作系统》课程设计
(
题目:
进程同步与互斥生产者-消费者问题
学习中心:
层次:
专业:
计算机网络技术
年级:
年秋季
学号:
学生:
辅导教师:
完成日期:
年月日
(
题目四:
进程同步与互斥生产者-消费者问题
设计思路:
生产者—消费者问题是一种同步问题的抽象描述。
计算机系统中的每个进程都可以消费或生产某类资源。
当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
流程(原理)图:
:
1、生产者
2、消费者
基本内容:
通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。
假定生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。
类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。
应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。
为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目,用g_hFullSemaphore表示,其初始值为有界缓冲区的大小SIZE_OF_BUFFER;另一个表示缓冲区中产品的数目,用g_hEmptySemaphore表示,其初始值为0。
另外,由于有界缓冲区是一个临界资源,必须互斥使用,所以还需要再设置一个互斥信号量g_hMutex,起初值为1。
、
在生产者/消费者问题中,信号量实现两种功能。
首先,它是生产产品和消费产品的计数器,计数器的初始值是可利用的资源数目(有界缓冲区的长度)。
其次,它是确保产品的生产者和消费者之间动作同步的同步器。
生产者要生产一个产品时,首先对资源信号量g_hFullSemaphore和互斥信号量g_hMutex进行P操作,申请资源。
如果可以通过的话,就生产一个产品,并把产品送入缓冲区。
然后对互斥信号量g_hMutex和资源信号量g_hEmptySemaphore进行V操作,释放资源。
消费者要消费一个产品时,首先对资源信号量g_hEmptySemaphore和互斥信号量g_hMutex进行P操作,申请资源。
如果可以通过的话,就从缓冲区取出一个产品并消费掉。
然后对互斥信号量g_hMutex和资源信号量g_hFullSemaphore进行V操作,释放资源。
如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。
如果有一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。
源代码:
//本程序于在VC++下运行通过
//系统环境:
WindowsXP
#include<>
[
#include
constunsignedshortSIZE_OF_BUFFER=20;//有界缓冲区长度
intg_buffer[SIZE_OF_BUFFER];//开辟缓冲区,用数组表示,可以看成是一个循环队列
unsignedshortProductID=0;//新生产出来的产品的产品号
unsignedshortConsumeID=0;//被消耗的产品的产品号
unsignedshortin=0;//产品进缓冲区时的缓冲区下标,用于记录生产者的指针位置
unsignedshortout=0;//产品出缓冲区时的缓冲区下标,用于记录消费者的指针位置
boolg_continue=1;//控制程序运行:
1表示继续运行,0表示停止运行
|
HANDLEg_hMutex;//线程间的互斥信号量
HANDLEg_hFullSemaphore;//资源信号量:
缓冲区满
HANDLEg_hEmptySemaphore;//资源信号量:
缓冲区空
DWORDWINAPIProducer(LPVOID);//生产者线程
DWORDWINAPIConsumer(LPVOID);//消费者线程
constunsignedshortPRODUCERS_COUNT=4;//生产者的个数
constunsignedshortCONSUMERS_COUNT=3;//消费者的个数
constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;//总线程数
*
HANDLEhThreads[PRODUCERS_COUNT];//各线程的handle
DWORDproducerID[CONSUMERS_COUNT];//生产者线程的标识符
DWORDconsumerID[THREADS_COUNT];//消费者线程的标识符
/*---------------生产一个产品开始-----------------*/
//生产一个产品,输出其ID号
voidProduce()
{
std:
:
cout< : endl; std: : cerr<<"生产一个产品: "<<++ProductID; std: : cout< : endl; } /*----------生产一个产品结束----------------*/ /*---------把新生产的产品放入缓冲区开始------------*/ //把新生产的产品放入缓冲区 voidAppend() ( { std: : cerr<<"把生产的产品送入缓冲区"; g_buffer[in]=ProductID; in=(in+1)%SIZE_OF_BUFFER; std: : cerr< : endl; std: : cout<<"缓冲区产品生产者/消费者"< : endl; //新产品放入缓冲区后,输出缓冲区当前的状态 for(inti=0;i 。 { //输出缓冲区下标 if(i<10) std: : cout< else std: : cout< if(i==in) { 、 if(g_buffer[i]<10) std: : cout<<""; else std: : cout<<""; std: : cout<<"<--生产者";//输出生产者的指针位置 } if(i==out) { ) if(g_buffer[i]<10) std: : cout<<""; else std: : cout<<""; std: : cout<<"<--消费者";//输出消费者的指针位置 } std: : cout< : endl; } { } /*------------把新生产的产品放入缓冲区结束--------------*/ /*--------------消费一个产品开始------------------*/ voidConsume()//消费一个产品 { std: : cout< : endl; std: : cerr<<"消费一个产品: "< std: : cout< : endl; % } /*-----------消费一个产品结束------------------*/ /*-----------从缓冲区中取出一个产品开始-------------*/ //从缓冲区中取出一个产品 voidTake() { std: : cout< : endl; / std: : cerr<<"从缓冲区取出一个产品"; ConsumeID=g_buffer[out]; out=(out+1)%SIZE_OF_BUFFER; std: : cerr< : endl; std: : cout< : endl; std: : cout<<"缓冲区产品生产者/消费者"< : endl; //取出一个产品后,输出缓冲区当前的状态 for(inti=0;i { //输出缓冲区下标 if(i<10) std: : cout< else std: : cout< if(i==in) { … if(g_buffer[i]<10) std: : cout<<""; else std: : cout<<""; std: : cout<<"<--生产者";//输出生产者的指针位置 } if(i==out) { 。 if(g_buffer[i]<10) std: : cout<<""; else std: : cout<<""; std: : cout<<"<--消费者";//输出消费者的指针位置 } std: : cout< : endl; } < } /*--------------从缓冲区中取出一个产品结束------------*/ /*------------生产者线程开始----------------*/ //生产者线程 DWORDWINAPIProducer(LPVOIDlpPara) { while(g_continue) , { //资源信号量的P操作 WaitForSingleObject(g_hFullSemaphore,INFINITE); //互斥信号量的P操作 WaitForSingleObject(g_hMutex,INFINITE); //生产一个产品 Produce(); //把新生产的产品放入缓冲区 ` Append(); Sleep(2000); //互斥信号量的V操作 ReleaseMutex(g_hMutex); //资源信号量的V操作 ReleaseSemaphore(g_hEmptySemaphore,1,NULL); } return0; 。 } /*---------生产者线程结束-----------------*/ /*-----------消费者线程开始--------------*/ //消费者线程 DWORDWINAPIConsumer(LPVOIDlpPara) { while(g_continue) & { //资源信号量的P操作 WaitForSingleObject(g_hEmptySemaphore,INFINITE); //互斥信号量的P操作 WaitForSingleObject(g_hMutex,INFINITE); //从缓冲区中取出一个产品 Take(); //消费一个产品 、 Consume(); Sleep(2000); //互斥信号量的V操作 ReleaseMutex(g_hMutex); //资源信号量的V操作 ReleaseSemaphore(g_hFullSemaphore,1,NULL); } return0; [ } /*-------消费者线程结束----------------*/ /*--------创建生产者线程开始--------------*/ voidcreatePT()//创建生产者线程 { for(inti=0;i { 。 hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]); if(hThreads[i]==NULL) g_continue=0; } } /*---------创建生产者线程结束-------------------*/ /*--------创建消费者线程开始-------------------*/ ! voidcreateCT()//创建消费者线程 { for(intj=0;j { hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[j]); if(hThreads[j]==NULL) g_continue=0; } } /*--------------创建消费者线程结束----------*/ /*---------主函数开始-----------*/ voidmain() { //显示程序提示信息 info(); //创建互斥信号量 g_hMutex=CreateMutex(NULL,FALSE,NULL); //创建资源信号量 g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL); //创建生产者线程 createPT(); //创建消费者线程 createCT(); //不按回车键的话程序会一直运行下去 while(g_continue) //按回车键终止程序 if(getchar()) g_continue=0; } /*--------------主函数结束-----------*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 大工 19 作业 答案
![提示](https://static.bdocx.com/images/bang_tan.gif)