大工20秋《操作系统》大作业答案.docx
《大工20秋《操作系统》大作业答案.docx》由会员分享,可在线阅读,更多相关《大工20秋《操作系统》大作业答案.docx(13页珍藏版)》请在冰豆网上搜索。
![大工20秋《操作系统》大作业答案.docx](https://file1.bdocx.com/fileroot1/2022-11/15/8d71c804-1950-4312-b0f7-a32e94832635/8d71c804-1950-4312-b0f7-a32e948326351.gif)
大工20秋《操作系统》大作业答案
学习中心:
专业:
计算机与网络技术
年级:
2020年春季
学号:
学生:
题目:
题目三:
进程同步与互斥生产者与消费者问题
1.谈谈你对本课程学习过程中的心得体会与建议?
单单抽象出生产者和消费者,还够不上是生产者—消费者问题。
该问题还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。
生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
单单抽象出生产者和消费者,还够不上是生产者—消费者问题。
该问题还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。
生产者把数据放入缓冲区,而消费者从缓冲区取出数据。
题目三:
进程同步与互斥生产者与消费者问题
总则:
不限制编程语言,可以选用C/C++等(具体工具平台及语言可以自己根据自己的习惯选用,不必完全按照上述技术要求)
要求:
(1)撰写一份word文档,里面包括(设计思路、流程(原理)图、源代码)章节。
(2)设计思路:
简单描述生产者与消费者问题。
可设计生产者进程主要计算进程,消费者进程输出打印进程,二者彼此独立,运行速度不确定,可能会产生还未生产就需要消费这种情况,此时引用一个或若干个缓冲区,存放生产者生产的信息,解决速度不确定带来的问题。
(3)流程(原理)图:
绘制流程图或原理图。
(4)源代码:
列出源代码,也可以仅列出伪代码。
(5)整个word文件名为[姓名奥鹏卡号学习中心](如戴卫东101410013979浙江台州奥鹏学习中心[1]VIP)
在多道程序环境下,系统中可能存在许多的进程,在这些进程之间必定存在一些制约关系,这种制约关系表现为以下两种形式:
①资源共享关系。
进程之间不知道其他进程的存在,而这些进程又处在同一个系统中,对系统资源必须共享使用,而有些资源不允许进程同时访问,例如打印机。
系统只能保证进程间互斥地使用这种临界资源,称这种资源共享关系叫做互斥;
②相互合作关系。
在某些进程间还存在一种相互合作的关系。
例如在某个系统中存在两个进程,输入进程A和计算进程B,A负责向B提供数据,当缓冲区空时,B进程因不能获得所需数据而等待。
当A把数据送入缓冲区后,并向B发送一个信号将B唤醒,B才能取走数据。
同样,当B没有提取数据,也就是说缓冲区满时,进程A也无法向其中投入数据而等待。
这就是一种相互合作关系,称之为进程间的同步关系。
设计思路:
生产者—消费者问题是一种同步问题的抽象描述。
计算机系统中的每个进程都可以消费或生产某类资源。
当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。
而当某个进程释放资源时,则它就相当一个生产者。
流程(原理)图:
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操作,释放资源。
如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。
如果有一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。
源代码:
//本程序于2005.12.25在VC++6.0下运行通过
//系统环境:
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(