操作系统课程设计 生产者与消费者

上传人:飞*** 文档编号:43665304 上传时间:2018-06-07 格式:DOC 页数:17 大小:594.50KB
返回 下载 相关 举报
操作系统课程设计 生产者与消费者_第1页
第1页 / 共17页
操作系统课程设计 生产者与消费者_第2页
第2页 / 共17页
操作系统课程设计 生产者与消费者_第3页
第3页 / 共17页
操作系统课程设计 生产者与消费者_第4页
第4页 / 共17页
操作系统课程设计 生产者与消费者_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《操作系统课程设计 生产者与消费者》由会员分享,可在线阅读,更多相关《操作系统课程设计 生产者与消费者(17页珍藏版)》请在金锄头文库上搜索。

1、燕山大学课程设计说明书燕山大学课程设计说明书课程设计名称:操作系统课程设计名称:操作系统 OSOS题目:题目:多道程序缓冲区协调操作多道程序缓冲区协调操作班级:班级: 开发小组名称:开发小组名称: 课题负责人:课题负责人: 课题组成员:课题组成员:姓名姓名 学号学号 班级班级 自评成绩自评成绩课题开发日期:课题开发日期:一、概述 利用 MFC 类库编写一个可实现多道程序缓冲区协调操作的面向对象的程序。1.1 基本功能 演示生产者消费者程序,多线程并发执行的过程;可以控制生产者消费者的个数及生产者生产的速度和消费者的速度,进度条中显示 Buffer中数据的个数,有五个按钮,分别为:开始、继续,暂

2、停、结束、退出,点击开始按钮,程序开始执行,点击暂停按钮,所有线程暂停执行,点击继续按钮,线程继续执行,结束按钮使得所有线程结束执行,点击退出按钮,退出系统,统计按钮按下时显示此时的 Buffer1,buffer2 的生产者生产的次数和 Buffer3 的消费者消费的次数,及 Move 的次数,和开始时间及结束时间。1.2 开发计划 10 号查阅参考资料,了解整体的框架结构; 11 号完成整体模块的构思及设计; 12 号完成程序具体的编写任务并调试代码; 13 号整理总结并书写报告; 14 号验收。1.3 人员分工 1.4 环境、工具和开发方法 本程序在 XP 系统下,采用的开发语言是 C+,

3、它是一种使用非常广泛的面向对象的计算机编程语言。它支持过程化程序设计、数据抽象、面向对象程序设计、制作图标等多种程序设计风格。 在 Visual C+ 6.0 编程环境中,利用 MFC 类库编写 C+风格的应用程序,基于 MFC 类库的应用程序可以快速建立起应用程序,并且类库为我们提供了大量的封装类。二、需求分析 用户需要看到看到并发程序的运行过程,以及能对过程进行控制,可以设计几个按钮控制开始,暂停、结束等功能,并可以让用户自定义生产者消费者数量及生产者消费者线程并发执行的速度,并能以用户能够明白的形式表示出来,可以设计一个进度条显示各个 Buffer 中的物品数量,并用数字显示出来,看的就

4、清楚了,设置一个统计按钮,当用户点击按钮时,就可以获取当前各个线程的情况,有几个线程在执行,Buffer1 的线程个数,Buffer2 的线程个数及从开始到结束所用的时间,从而了解线程运行的情况。三、软件设计 2.1 设计思想设计了 3 个主要函数,分别为:生产者函数 put、消费者函数 get、转移函数 move 下面详细介绍各个类的功能。Put 函数用于实现通过执行 P 操作判断 buff1 是否有空,buff1 是否可操作,并向 buff1 中置数据,同时将表示 buff1 中数据数 buffnumber1加+1,将表示操作 put 操作的 allnumber1+,实现计数操作,放入数据

5、后执行 V 操作。Move 函数通过执行 P 操作来判断 buff1 中是否有数据,是否可操作,buff2 中是否有空间,是否可操作,将 buff1 中的数据移至 buff2 中,并使 buffer1number-,buffer2number+,确定 buff 中现有的数据总数。之后再进行相应的 V 操作。Get 函数和 Put 函数类似通过创建自己所需的图形界面编写各个图标所要实现功能的函数。2.2 设计原理生产者消费者问题是相互合作的进程关系的一种抽象,可以利用信号量机制来解决生产者消费者问题,利用互斥信号量 mutex 实现进程对缓冲池的互斥使用。对信号量的操作只能通过两个原子操作:Wa

6、it(s)和Signal(s).Wait(s)是等待信号的操作,进行 S=S-1 操作;Signal(s)是发送信号的操作,进行 S=S+1 操作。 wait 若 s-1 后仍大于或等于零,则进程继续执行;若 s-1 后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度;若相加结果大于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度如下图所示,有 10 个 PUT(相当于生产者)操作要不断循环地向Buffer1 送数据,有一个 Move(相当于搬运者)操作要不断地将 Buffer1的数据取到 Buffer2,有 20 个 GET(相当于消费者

7、)操作要不断地从Buff2 中取数据。BUFF1 是 10,BUFF2 的容量是 20, PUT、 MOVE、 GET 每次操作一个数据,为了在操作的过程中要保证数据不丢失,每个 Buffer 每次只能接受一个 PUT 或一个 Move 或一个 Get,多个操作不能同时操作同一 BUFFER。设计一个多道程序完成上述操作。试用、原语协调 PUT、 MOVE、GET 的操作,并说明每个信号量的含义、初值和值的范围。PUT MOVE GET 图 1 Buffer 操作2.3 线程规划我们创建三类线程: (1)PUT 线程(往 BUFFER1 里放数据,相当于生产者) 。 (2)MOVE 线程(从

8、BUFFER1 里取数据并放到 BUFFER2 里,相当于搬运者) 。 (3)GET 线程(从 BUFFER2 里取数据,相当于消费者) 。 每类线程可由用户自行设定线程的个数。2.4 信号量的设置需要设置六个信号量 full1 empty1 buff1 full2 empty2 buff2。各信号量含义及初值如下:full1 表示 buffer1 是否有数据,初值为 0;empty1 表示 buffer1 是否有空间,初值为 m;buff1 表示 buffer1 是否可操作,初值为 1;full2 表示 buffer2 是否有数据,初值为 0;empty2 表示 buffer2 是否有空间,

9、初值为 n;buff2 表示 buffer2 是否可操作,初值为 1。四、编码设计 void CHomeworkDlg:OnPaint() /定义画图的颜色和大小if (IsIconic()CPaintDC dc(this); / device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);/ Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemM

10、etrics(SM_CYICON);CRect rect;GetClientRect(int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;/ Draw the icondc.DrawIcon(x, y, m_hIcon);elseCPaintDC dc(this);COLORREF col;for(int i=1;iSelectObject(pDC-BeginPath();pDC-MoveTo(rc.left,rc.top+rc.Height()/4);pDC-LineTo(rc.ri

11、ght-rc.Width()/4,rc.top+rc.Height()/4);pDC-LineTo(rc.right-rc.Width()/4,rc.top);pDC-LineTo(rc.right,rc.top+rc.Height()/2);pDC-LineTo(rc.right-rc.Width()/4,rc.bottom);pDC-LineTo(rc.right-rc.Width()/4,rc.bottom-rc.Height()/4);pDC-LineTo(rc.left,rc.bottom-rc.Height()/4);pDC-LineTo(rc.left,rc.top+rc.Hei

12、ght()/4);pDC-EndPath();pDC-FillPath();pDC-SelectObject(oldBrush);UINT put(LPVOID lparam)/put 操作CHomeworkDlg * dlg =(CHomeworkDlg *) lparam;int i =dlg-current;while(!dlg-bkill)p(dlg-full1);p(dlg-buffer1);dlg-putid=i;dlg-buffer1number+=1;dlg-bput=TRUE;dlg-allnumber1+;:Sleep(dlg-DELAY);v(dlg-buffer1);v

13、(dlg-empty1);dlg-bput=FALSE;return 0;UINT move(LPVOID lparam)/move 操作CHomeworkDlg *dlg = (CHomeworkDlg *)lparam;int i =dlg-current;while(!dlg-bkill)p(dlg-empty1);p(dlg-full2);p(dlg-buffer1);p(dlg-buffer2);dlg-bmove=TRUE;dlg-buffer1number-;dlg-buffer2number+;dlg-moveid=i;:Sleep(dlg-DELAY);/v(dlg-buff

14、er1);v(dlg-buffer2);v(dlg-empty2);v(dlg-full1);dlg-bmove=FALSE;return 0;UINT get(LPVOID lparam)/get 操作CHomeworkDlg * dlg = (CHomeworkDlg *)lparam;int i =dlg-current;while (!dlg-bkill)p(dlg-empty2);p(dlg-buffer2);dlg-getid=i;dlg-buffer2number-;dlg-bget=TRUE;dlg-allnumber2+;:Sleep(dlg-DELAY);v(dlg-buf

15、fer2);v(dlg-full2);dlg-bget=FALSE;return 0;void CHomeworkDlg:OnButton1() if(bmove|bget|bput)/判断是否有线程在运行,如果正在进行输出MessageBox(“线程正在运行“);return;if(binstall)this-OnButton3();allnumber1=allnumber2=alltime =0;this-SetTimer(3,100,0);/设定个毫秒的计时器bkill=FALSE;/CWinThread * pthread;/定义线程指针for(int m=1;mcurrent=m;/

16、第几个线程pthread = AfxBeginThread(move,this);/创建线程函数启动线程hdm-1 =pthread-m_hThread;/赋值给 hdfor(int i=1;icurrent=i;pthread = AfxBeginThread(put,this);hdm_move+i = pthread-m_hThread; /将 put 存储到move 后for(int j=1;jcurrent=j;pthread = AfxBeginThread(get,this);hdm_move+m_put+j = pthread-m_hThread;void CHomeworkDlg:On

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号