苹果-桔子问题的实现 下载本文

2.概要设计

2.1数据结构

在此次程序中一共涉及到线程、函数、互斥信号、信号量和常变量。在本程序中使用了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互斥信号进行设置,以释放资源。 有两类生产者,一类负责生产桔子,一类负责生产苹果:有两类消费者,一类负责消费桔子,一类负责消费苹果;他们共享一个有储存单元的有界缓冲区,每个存储单元只能放入一种(桔子或苹果)。二类生产者与二类消费者数目固定,即一个生产者负责生产桔子,一个个生产者负责生产苹果;一个个消费者负责消费桔子,一个消费者负责消费苹果。二类生产者的生产速度与二类消费者额消费速度均可独立在程序界面调节,在运行中,该值调整后立即生效;多个生产者或多个消费者之间必须有共享对缓冲区进行操作的函数代码,同时需要考虑算法的效率性。每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容、每当生产者与消费者的指针位置,以及生产者的消费者线程标识符。

(1)用一个整型变量plat_size表示盘子,初始值为0,plat_size=apple+orange,当

4

放水果plat_size加1,取水果plat_size减1。当plat_size为1时,表示盘子已满,此时若进行放水果操作,放水果将处于等待状态;当为0时,表示盘子已空,此时若进行取水果操作,取水果操作将处于等待状态。

(2)整型变量orang和apple分别表示盘中桔子和苹果的数目,初始值都为0.。 (3)用4个整型变量father_lag、mother_lag、son_lag、daughter_lag表示4个进程是否处于等待状态,处于等待状态时,变量值为1。

(4)两个水果同时处等待状态时,若有取水果的操作将自动执行等待放水果进程,执行按等待的先后顺序。

(5)用一个随机函数产生0~3的4个整数,分别对应4个进程调用。 int apple=0; //苹果个数 int orange=0; //桔子个数 int father_lag=1; //father进程标志 int mother_lag=1; //mother进程标志 int son_lag=1; // son进程标志 int daughter_lag=1; //女儿进程标志 int plat_size=0; //盘子中水果数量 int mf=0; //father与mother进程等待先后

2.2模块声明

本程序共创建了4个在windows系统环境下实现的线程,即Fahter、Mother、Son和Daughter等4个线程,以及putapple、putorange、getapple和getorange等4个函数,其中4个线程是用于实现爸爸、妈妈、儿子和女儿分别放水果和取水果的线程操作的,并分别调用这4个函数,来实现真正的操作。在本程序中还设置了mutex互斥信号、empty、apple和orange等信号量,用于各线程之间获取资源和放弃资源等的线程之间的操作控制,并且设置了盘子容量上线常量content。其主要功能是用于实现爸爸和妈妈这2个互斥线程对于资源的使用操作以及爸爸和女儿、妈妈和儿子这2组同步线程对于资源的操作。若干个函数组成一个程序文件,若干个程序文件组成一个完整的程序,因此函数是程序的基本组成部分。在本程序中共创建了putapple( )、putorange( )、getapple( )和getorange( )等4个功能函数,分别用来模拟实现放苹果、放橘子、取

5

苹果和取橘子的操作。主函数main( )主要作用就是为Father、Mother、Son和Daughter这四个线程服务,创建这几个线程,并在这些线程执行完毕后销毁它们。主函数中Sleep( )函数,控制主线程休眠一段时间,并在此期间执行其他其他子线程,在休眠时间过后主线程执行完,整个程序执行完毕。 (1)主模块

用一个随机函数产生0~3的4个整数,分别对应4个进程的调用,调用的次数可以自己输入,本程序共产生10次随机调用过程。 (2)4个进程模块

爸爸向盘中放一个苹果操作:father() 妈妈想盘中放一个桔子操作:mother() 儿子从盘中取一个桔子操作:son() 女儿从盘中取一个苹果操作:daughter() (3)printf()输出模块

用于输出盘中苹果和桔子的个数及有哪些进程处于等待状态。 (4)4个bool型的变量

Father_lag,Mother_lag,Son_lag,Daughter_lag,表示四个进程是否处于等待状态。处于等待时,变量值为true。

6

3.详细设计

3.1界面设计

1、系统分析 此次设计是实现特殊生产者和消费者的演示程序,所需要处理的信息是生产者和消费者的个数,生产苹果、橘子和消费苹果、橘子的速度控制,缓冲区中橘子和苹果的个数和当 前生产、消费指针的位置。

2、程序中需要处理缓冲区的动态显示、生产者和消费者的速度可以调节,生产者和消费 者个数可以改变。为了实现界面的友好性,应该对用户标明清楚各个模块的作用。同时实时 的对程序进行暂停和停止。 演示程序中用图形显示的方法描述缓冲区的使用情况, 即当前缓 冲区有多少个苹果和橘子,还有生产和消费者的指针。

3、系统对外的界面如下: 可以调节橘子和苹果的生产速度和消费苹果和橘子的速度,在文本框中输入相应的速 度,再按下修改按键即可实现速度的实时调节。 在苹果生产者、橘子生产者、苹果消费者、橘子消费者中实现对个数按钮的按下即可动态实时的调节生产者和消费者的个数的调节。

4、两个放水果进程同时处于等待状态时,若有取水果的操作将自动执行等待的放水果进程,执行按等待的先后顺序自动调用;取苹果或橘子进程同时处于等待状态,若有放苹果或橘子的操作将自动执行等待的取水果进程,进行按等待的先后顺序自动调用。界面设计用于输出盘中苹果和桔子的个数及有哪些进程处于等待状态。根据题目要求,该设计需要有四个进程;有一个公用存储单元缓冲区。用4个整型变量father_lag、mother_lag、son_lag、daughter_lag表示4个进程是否处于等待状态,处于等待状态时,变量值为1。

3.2算法设计

在本系统中,爸爸与妈妈、儿子与女儿的线程操作是互斥的,但是爸爸与女儿、妈妈与儿子线程之间的操作是同步的。因此要利用进程同步的方法来实现这几者之间的操作,当然其中也包含着互斥进程,因为盘子每次只能放入或者取出一个水果。因为是在windows操作系统下实现的,所以是采用线程的方法实现的。 本程序算法使用if~else结构和for循环结构,该算法中有两类生产者。一类负责生产橘子,一类负责生产苹果;有两类消费者,一类负责消费橘子,一类负责消费苹果。他们共享存储单元的缓冲区。每种存储单元仅能放入一种产品(苹果或橘子)。二类生产者的生产速度与二类消费者的消费速度均可独立于程序界面上调节。每个生产者和消费者对有界缓冲区进行操作之

7