燕山大学课程设计说明书

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

燕山大学课程设计说明书

课程设计名称:操作系统

题目:多道程序缓冲区协调操作

班级:11级计算机应用1班

开发小组名称:多道程序缓冲区协调操作的程序设计课题负责人:吴楠

课题组成员:姓名吴楠学号 110104010058

班级应用1班自评成绩

姓名王乐学号 110104010045

班级应用1班自评成绩

课题开发日期:2014.1.10

1 概述

1.1 课程设计目的

通过编写一个生产者消费者的实例,了解多线程的创建,运行原理,通过信号量机制的运用了解各线程间的协调工作机制;通过实现界面编程,了解MFC 编程思想。

1.2 主要完成的任务

如下图所示,有多个PUT 操作要不断循环地向Buffer1送字符数据,有Move1操作不断地将Buffer1的数据取到Buffer2,Move2操作不断地将Buffer1的数据取到Buffer3,有多个GET 操作要不断地从Buffer2和Buffer3中取数据。PUT 、 MOVE 、 GET 每次操作一个数据,为了在操作的过程中要保证数据不丢失, 每个Buffer 每次只能接受一个PUT 或一个Move 或一个Get 。运用进程同步和互斥机制设计一个多道程序完成上述操作。

图1 Buffer 操作

(1) 可以随机产生字符数据,由put 操作放入Buff1,buffer 中容量单位是字符。

(2)提供良好图形界面,显示Buffer 的操作过程。

(3) 可以设定各Buffer 的容量、PUT 、GET 、Move 操作的个数;

(4) 可以设定PUT 、GET 、Move 操作的速度;

(5) 实时显示每个Buffer 中数据的个数和数据的内容,空闲Buffer 的空间的个数;

(6) 实时显示线程、进程所处于等待(阻塞)状态的个数

(7)程序运行结束,显示汇总数据:

总的运行时间;

Buffer 中数据的个数;

已放入BUFFER 的数据个数;

已取出的数据个数;

平均每个buffer 中的数据个数。

Put Move2 Buff1 Buff2 Buff3 Get Move1 Get

1.3 课程设计使用的开发语言和工具

语言:C++

开发环境:Visual Studio 2008及其开发环境下的MFC平台。

1.4 解决的主要问题

(1)MFC界面设计

(2)模拟生产者消费者的互斥操作

(3)各信号量的使用

2 使用的基本概念和原理

2.1 MFC

MFC是Windows下程序设计的最流行的一个类库,它合理的封装了WIN32 API函数,并设计了一套方便的消息映射机制。

2.2 MFC的消息实现机制

在MFC的框架结构下,可以进行消息处理的类的头文件里面都会含有DECLARE_MESSAGE_MAP()宏,这里主要进行消息映射和消息处理函数的声明。

所有能够进行消息处理的类都是基于CCmdTarget类的,也就是说CCmdTarget类是所有可以进行消息处理类的父类。CCmdTarget类是MFC处理命令消息的基础和核心。

2.3 线程

线程是程序独立运行的基本单位,一个程序通过执行多个线程可以提高机器本身资源的利用率,同时也可以完成多任务并行运行的操作。

2.4 信号量

信号量是一个在一定范围内变化的整形数据,用来表示一种临界资源,线程通过信号量的值来确定自己的状态是执行还是挂起,各线程间也是通过信号量机制来协调运行顺序一起完成任务。

3 总体设计

3.1基本的技术路线

确定基本技术路线为面向对象程序设计,使用MFC编写程序,建立基本对话框。

在对话框中设立生产者、MOVE、消费者板块,各板块内的按钮能控制各自线程的建立、暂停以及相关数据的设定。

3.2软件的总体结构

图2 总体结构

3.3模块关系

主要分为显示模块、数据模块和线程模块。模块之间的关系显示模块显示的数据模块的内容,而数据模块又影响线程模块,三个模块互相影响,并根据各自的变化,实时显示并协调工作。

3.4总体流程

通过创建生产者线程往BUFFER1中投放随机产生的字符,创建MOVE1线程和MOVE2线程将BUFFER1中的字符移动到BUFFER2和BUFFER3中,创建消费者线程从BUFFER2和BUFFER3中取出字符消费。

建立信号量,因为生产者线程和MOVE1、MOVE2线程共同使用临界资源BUFFER1,所以用Mutex1信号量来协调生产者线程和MOVE1和MOVE2线程;因为MOVE1线程和MOVE2线程共同使用临界资源BUFFER1,因为MOVE1线程和消费者线程GET1共同使用临界资源BUFFER2,MOVE2线程和消费者线程GET2共同使用临界资源BUFFER2,所以用Mutex23信号量来协调MOVE1线程和消费者线程GET1,用Mutex3信号量来协调MOVE2线程和消费者线程GET2。

4 详细设计

4.1r ThreadInfo结构体

typedef stuct ThreadInfo{

CListBox *pList;

}thread,*lpthread;

此结构体用来保存在线程建立时往线程中传送的参数信息(如该线程指定的操作控件),以供在本线程中使用。

4.2 线程操作函数

4.2.1 执行函数的声明

//声明PUT线程。

DWORD WINAPI ThreadPut(LPVOID lpParameter);

//声明MOVE1线程。

DWORD WINAPI ThreadMove1(LPVOID lpParameter);

//声明MOVE2线程。

DWORD WINAPI ThreadMove2(LPVOID lpParameter);

//声明GET线程,主要区别是能分别输出该消费的字符是哪个消费者消费的。DWORD WINAPI ThreadGet(LPVOID lpParameter);

4.2.2 各信号量的定义

Mutex = CreateMutex(NULL,false,NULL);

Mutex1 = CreateMutex(NULL,false,NULL);

Mutex2 = CreateMutex(NULL,false,NULL);

SemaphoreEmpty1=CreateSemaphore(NULL,m_buffer1,m_buffer1,NULL);

SemaphoreFULL1=CreateSemaphore(NULL,0,m_buffer1,NULL);

SemaphoreEmpty2=CreateSemaphore(NULL,m_buffer2,m_buffer2,NULL);

SemaphoreFULL2=CreateSemaphore(NULL,0,m_buffer2,NULL);

SemaphoreEmpty3=CreateSemaphore(NULL,m_buffer3,m_buffer3,NULL);

SemaphoreFULL3=CreateSemaphore(NULL,0,m_buffer3,NULL);

4.2.3各线程的函数接口的定义及算法描述

PUT线程函数接口:

DWORD WINAPI ThreadPut(LPVOID lpParameter)//put线程的入口函数

{

while(toend)

{

Sleep(speed1);

CString str;

str= rand()%128; //生成随机字符

WaitForSingleObject(SemaphoreEmpty1,INFINITE);//申请空间实现P(Empty1)

相关文档
最新文档