当前位置:文档之家› 进程同步模型系统的设计—吃水果

进程同步模型系统的设计—吃水果

课程设计课程设计任务书学生: Miss屠专业班级: 08计科指导教师:王海英工作单位:计算机科学与技术学院题目: 进程同步模型系统的设计——吃水果问题初始条件:1.预备容:阅读操作系统的进程管理章节容,对进程的同步和互斥,以及信号量机制度有深入的理解。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.为下面吃水果的问题创建进程并利用通信API实现进程之间的同步模型。

能够处理以下的情形:桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。

爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,两个儿子专门等待吃盘子中的橘子,两个女儿专门等吃盘子中的苹果。

2.设计报告容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);时间安排:设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:撰写课程设计报告。

指导教师签名:年月日系主任(或责任教师)签名:年月日进程同步模型系统的设计——吃水果问题1、课程设计目的与功能1.1、目的为下面吃水果的问题创建进程并利用通信API实现进程之间的同步模型。

能够处理以下的情形:桌子上有一只盘子,最多可容纳两个水果,每次只能放入或者取出一个水果。

爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,两个儿子专门等待吃盘子中的橘子,两个女儿专门等吃盘子中的苹果。

1.2、实现的功能本程序共创建了4个在windows系统环境下实现的线程,即Fahter、Mother、Son和Daughter等4个线程,以及putapple、putorange、getapple和getorange 等4个函数,其中4个线程是用于实现爸爸、妈妈、儿子和女儿分别放水果和取水果的线程操作的,并分别调用这4个函数,来实现真正的操作。

在本程序中还设置了mutex互斥信号、empty、apple和orange等信号量,用于各线程之间获取资源和放弃资源等的线程之间的操作控制,并且设置了盘子容量上线常量content。

其主要功能是用于实现爸爸和妈妈这2个互斥线程对于资源的使用操作以及爸爸和女儿、妈妈和儿子这2组同步线程对于资源的操作。

2、需求分析当计算机中两个或者多个进程在执行时需要使用公用缓冲区,并且对该缓冲区采取了互斥措施,这时如果并发执行这些进程的时候就会造成CPU时间的极大浪费,这是操作系统设计要求不允许的。

而这种现象在操作系统和用户进程量存在。

因此为了解决这一问题,提出了同步的概念,即把异部环境下的一组并发进程,因直接制约而互相发送消息而进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步。

在本系统中,爸爸与妈妈、儿子与女儿的线程操作是互斥的,但是爸爸与女儿、妈妈与儿子线程之间的操作是同步的。

因此要利用进程同步的方法来实现这几者之间的操作,当然其中也包含着互斥进程,因为盘子每次只能放入或者取出一个水果。

因为是在windows操作系统下实现的,所以是采用线程的方法实现的。

3、整体功能及设计3.1数据结构的设计在此次程序中一共涉及到线程、函数、互斥信号、信号量和常变量。

3.1.1线程线程是指进程的一个执行单元,也是进程的可调度实体。

单个进程在任何给定时刻,可能有不止一个线程在运行。

但进程启动的同时启动了一个线程,该线程被称作主线程或执行线程。

一个进程除启动主线程外还可以启动多个线程,每个线程都共享进程的地址空间,并且共享着进程的地址空间及各种资源。

线程可以继续创建子线程。

如果主线程退出,主线程下的所有子线程将失败。

线程的创建格式如下:其中括号中则需要列出该函数的各形参或者实参。

该函数的返回值为线程的句柄。

HANDLE CreateThread( );CreateThread函数参数说明在本程序中使用了Father、Mother、Son和Daughter等共4个线程。

Father、Mother线程的作用是模拟实现向盘子中放苹果或者橘子的操作,当主程序执行之后创建了Father或者Mother线程,则该线程会独自占用整个资源,并执行putapple或者putorange函数来实现操作,在执行Father或者Mother 线程时,首先会将信号量empty减1,来说明盘子中已经放置了一个水果,之后将互斥信号mutex置0,来说明盘子已经被占用,其他进程无法占用。

当实现了putapple或者putorange后,该线程会置mutex为1,来释放资源,表明该资源可以被其他线程所使用。

接下来将apple或者orange信号进行相应的设置,表明在盘子中已经放置了苹果或者橘子,Daughter或者Son线程可以从盘子中取苹果或者橘子了。

Daughter 、Son线程的作用是模拟实现从盘子中取出苹果或者橘子的操作,当主程序中执行过Father或者Mother线程之后会释放资源,这时候Daughter 或者Son线程便得到了资源,在得到资源即盘子后会首先将apple或者orange 信号量进行设置,恢复原来的数值以表明盘子中的水果情况,并且将mutex互斥信号进行设置,表示资源正在被占用。

在实现了getapple或者getorange后,便对mutex互斥信号进行设置,以释放资源。

3.1.2函数若干个函数组成一个程序文件,若干个程序文件组成一个完整的程序,因此函数是程序的基本组成部分。

在本程序中共创建了putapple( )、putorange( )、getapple( )和getorange( )等4个功能函数,分别用来模拟实现放苹果、放橘子、取苹果和取橘子的操作。

主函数main( )主要作用就是为Father、Mother、Son和Daughter这四个线程服务,创建这几个线程,并在这些线程执行完毕后销毁它们。

主函数中Sleep( )函数,控制主线程休眠一段时间,并在此期间执行其他其他子线程,在休眠时间过后主线程执行完,整个程序执行完毕。

3.1.3互斥信号和信号量线程同步的方法有很多,最常用的有互斥(CMutex)、临界(CriticalSection)、信号量(Semaphore)和事件(Event)。

但本程序只用到了互斥和信号量。

其中mutex是各线程之间的互斥信号,当一个线程占用了资源之后,其他线程在没接收到通知的时候即互斥信号为0时便无法使用资源。

empty、apple和orange为3个信号量,分别来表示资源的使用状态,各线程根据这3个信号量来了解资源状态和使用资源。

这3个信号量的变化围为0~ content,content为盘子的容量,也是资源的容量。

3.2程序实现框图3.2.1 main函数3.2.2 Father、Mother线程3.2.3 Son、Daughter线程4、编程实现4.1各线程的声明:DWORD WINAPI Father(LPVOID lpParameter);//Father线程DWORD WINAPI Mother(LPVOID lpParameter);//Mother线程DWORD WINAPI Son(LPVOID lpParameter);//Son线程DWORD WINAPI Daughter(LPVOID lpParameter);//Daughter线程4.2 各信号量、互斥信号和常变量HANDLE mutex;//互斥信号mutexHANDLE empty; //信号量emptyHANDLE apple; //信号量appleHANDLE orange; //信号量orangeconst int content=2; //常变量mutex4.3个函数的声明void putapple( );void putorange( );void getapple( );void getorange( );4.4主函数的程序代码void main(){mutex=CreateMutex(NULL,FALSE,NULL);//创建mutexempty=CreateSemaphore(NULL,content,content,NULL); //创建empty apple=CreateSemaphore(NULL,0,content,NULL); //创建appleorange=CreateSemaphore(NULL,0,content,NULL); //创建oarngeHANDLE hThread1;HANDLE hThread2;HANDLE hThread3;HANDLE hThread4;hThread1=CreateThread(NULL,0,Father,NULL,0,NULL);//创建Father线程hThread2=CreateThread(NULL,0,Mother,NULL,0,NULL);//创建Mother线程hThread3=CreateThread(NULL,0,Son,NULL,0,NULL);//创建Son线程hThread4=CreateThread(NULL,0,Daughter,NULL,0,NULL);//创建Daughter 线程CloseHandle(hThread1);//销毁Father线程CloseHandle(hThread2);//销毁Mother线程CloseHandle(hThread3);//销毁Son线程CloseHandle(hThread4);//销毁Daughter线程Sleep(35000);//主程序将在30秒后结束}4.5各线程的程序代码DWORD WINAPI Father(LPVOID lpParameter)//Father线程实现{while(1){WaitForSingleObject(empty,INFINITE);WaitForSingleObject(mutex,INFINITE);putapple( );Sleep(1500);ReleaseMutex(mutex);ReleaseSemaphore(apple,1,NULL);}}DWORD WINAPI Mother(LPVOID lpParameter)//Mother线程实现{while(1){WaitForSingleObject(empty,INFINITE);WaitForSingleObject(mutex,INFINITE);putorange( );Sleep(1500);ReleaseMutex(mutex);ReleaseSemaphore(orange,1,NULL);}}DWORD WINAPI Son(LPVOID lpParameter)//Son线程实现{while(1){WaitForSingleObject(orange,INFINITE);WaitForSingleObject(mutex,INFINITE);getorange( );Sleep(1500);ReleaseMutex(mutex);ReleaseSemaphore(empty,1,NULL);}}DWORD WINAPI Daughter(LPVOID lpParameter)//Daughter线程实现{while(1){WaitForSingleObject(apple,INFINITE);WaitForSingleObject(mutex,INFINITE);getapple( );Sleep(1500);ReleaseMutex(mutex);ReleaseSemaphore(empty,1,NULL);}}4.6各函数的程序代码void putapple( )//Father放苹果{cout<<"爸爸要放苹果了!"<<endl;Sleep(1500);cout<<"苹果已经被放进去了!"<<endl;}void putorange( )//Mother放橘子{cout<<"妈妈要放橘子了!"<<endl;Sleep(1500);cout<<"橘子已经被放进去了!"<<endl; }void getapple( )//Daughter取苹果{cout<<"女儿要吃苹果了!"<<endl;Sleep(1500);cout<<"苹果已经被拿出来了!"<<endl; }void getorange( )//Son取橘子{cout<<"儿子要吃橘子了!"<<endl;Sleep(1500);cout<<"橘子已经被拿出来了!"<<endl; }5、运行结果与运行情况分析程序的运行结果如下:各线程执行完一次的结果:由于是设定了Sleep( )函数,所以程序在执行了35000毫秒,即35秒之后便自动结束。

相关主题