版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、精选优质文档-倾情为你奉上 燕山大学课程设计说明书课程设计名称:操作系统 题目:多道程序缓冲区协调操作 (模拟生产者消费者问题) 课题负责人: 学院: 信息科学与工程学院 班级: 姓名: 学号: 课题开发日期:2014年1月13日 自评成绩: A 目录1 概述-31.1 目的-31.2 主要完成的任务-31.3 使用的开发工具、开发语言-31.4 本软件解决的主要问题 -42 设计的基本理念、概念和原理-42.1 设计的基本理念-42.2 基本概念-42.3 基本原理-53 总体设计-53.1基本的技术路线:面向对象-53.2模块关系及总体流程-54 详细设计-74.1 变量设计-74.2 线
2、程的设计-74.3 button按钮的设计-85编码设计-95.1开发环境-95.2注意事项-95.3主要代码设计-9PUTTER线程的设计-9MOVER1线程的设计-10GETTER1线程的设计-11“开始”按钮的设计-12“结束”按钮的设计-145.4解决的主要难题-166测试出现的问题及其解决方案-167工程总结-168参考文献-16多道程序缓冲区协调操作演示程序设计说明书1 概述1.1 目的计算机操作系统是计算机系统中最不可缺少的,最常用的软件,也是核心的,最接近于计算机硬件的软件。其特点是内容繁多,概念抽象,因此造成理解困难,掌握不易。本软件的主要目的是通过直观的演示,使学生能够感性
3、的明白掌握多道程序及其进程同步和互斥的程序设计的基本方法。1.2 主要完成的任务(1) 可随机产生字符数据,由生产者的put操作不断将生产的字符数据放入容器1(Buffer1)中。(2) 通过搬运者的Move1操作要不断地将容器1(Buffer1)的数据取到容器2(Buffer2)中。(3) 通过搬运者的Move2操作要不断地将容器1(Buffer1)的数据取到容器3(Buffer3)中。(4) 通过消费者1的GET操作不断的从容器2(buffer2)中取出数据(5) 通过消费者2的GET操作不断地从容器3(Buffer3)中取出数据。(6) 生产者,搬运者,消费者的数目,buffer容量可自
4、己设定,但数目不宜过多;默认为生产者5,消费者1为5,消费者2为5,Move1为2,Move2为2,buffer1容量为10,buffer2容量为10,buffer3容量为10。(7) PUT、 Move1、Move2、 GET1,GET2每次操作一个数据,在操作的过程中数据不丢失,每个Buffer每次只能接受一个PUT或一个Move或一个Get,多个操作不能同时操作同一BUFFER。(8) 能够实时显示Buffer的操作过程,以及每个Buffer的当前放入的数据,每个buffer中的数据的个数。(9) 能够对生产者,搬运者,消费者的速度进行自由控制。(10) 当程序运行开始后,计时器就开始计
5、时,直到运行结束,显示运行的总时间。(11) 运行结束后,能够汇总总运行时时间、已生产产品数、消费者1已消费产品数、消费者2已消费的产品数、总消费的产品数。1.3使用的开发工具、开发语言开发工具:VS2010开发语言:C+C+是面向对象的一种编程语言,窗口程序设计中MFC已经将windows最底层的API函数以类的形式封装好,使用方便。 其特点有:1.面向对象; 2.平台无关性; 3.安全性; 4.健壮性;1.4本软件解决的主要问题对Buffer操作的多线程同步问题,利用操作系统的P、V原语操作和C+语言的Thread线程对put、move、get等多线程进行协调处理,实现了多线程并发执行的原
6、理。用程序演示了操作系统中经典的生产者和消费者问题。2 设计的基本理念、概念和原理2.1 设计的基本理念使用VS2010创建了一个基本对话框类,并在对话框中添加了基本需要的所有控件:(1) buffer1,buffer2,buffer3三个LISTBOX控件,用于显示各个buffer中的当前内容。(2) 添加了3个编辑框控件,分别用于对3个容器(buffer)容量的控制。(3) 添加1个编辑框控件用于输入数值确定线程执行速度。(4) 添加5个编辑框控件,用于对生产者,移动物流,消费者数量的控制。五个线程用于对buffer容器的控制(PUTTER,MOVER1,MOVER2,GETTER1,GE
7、TTER2):(1) PUTTER线程产生随机字符,并放入buffer1中,实现生产者的生产过程。(2) MOVER1,MOVER2线程分别将buffer1中的数据移动至buffer2 和buffer3中。(3) GETTER1,GETTER2线程分别将buffer2和buffer3中的数据字符移出,实现消费者的消费过程。多个变量分别统计需要显示的数据:(1) 三个变量分别统计buffer1,buffer2,buffer3中的数据并实时显示出来。(2) 五个变量进行数据汇总,显示最后的运行总时间,生产者生产数量,消费者消费数量 。 通过MFC的对话框中按钮实现对所有线程的控制:(1) “开始”
8、按钮:开始所有线程,实现多线程程序同步。(2) “结束”按钮:结束所有线程,并显示数据汇总情况。2.2 基本概念面向对象,进程,线程,线程的同步,线程的互斥,多道程序。2.3 基本原理经典的生产者与消费者同步原理,通过互斥体和互斥信号来实现线程的等待,线程间的同步问题,线程之间的协调的问题。3.总体设计3.1基本的技术路线:面向对象运用面向对象的设计理念,设计所要求的PUTTER,MOVER1,MOVER2,GETTER1,GETTER2五个线程,达到信号量的控制,变量的值确定,实现BUFFER一次只能操作一个动作,实现线程的同步,阻塞以及他们之间的协调问题。Pca对话框类:主界面设计、显示数
9、据、过程演示PUTTER线程:生产者:执行put操作MOVER1线程:搬运者1:执行move1操作GETTER1线程:消费者1:执行get 操作MOVER2线程:搬运者2:执行move2操作GETTER2线程:消费者2:执行get操作3.2 模块关系及总体流程 图1. 模块关系参数设定(或使用默认数据)开始运行(速度控制)结束动态显示每个buffer中的字符数据内容,移动过程以及数量数据汇总显示退出 图2.总体流程4.详细设计 4.1变量设计 g_hMutex1,g_hMutex2,g_hMutex3:三个互斥体,分别控制一次只能对buffer实现一次操作。 g_hFullItems1,g_h
10、FullItems2,g_hFullItems3 g_hEmptyItems1,g_hEmptyItems2,g_hEmptyItems3: 六个信号量,分别控制buffer中是否有空闲空间以及是否有数据可供移动,并进行互斥操作。 clock_t类型的 start,finish变量,通过调用clock()函数得到线程运行的总时间。 struct PThread int ptid; CpacDlg * dlg; 定义线程的结构体,用于线程通过结构体参数调用窗口类,从而实现线程对窗口的控制。 SIZE_1, SIZE_2, SIZE_3:编辑框控件添加的变量,从而实现动态对容器buffer容量的控
11、制。 SPEED:控件添加的变量,实现对线程速度的控制。 Produce_Num ,Consumer1_Num ,Consumer2_Num ,Move1_Num ,Move2_Num:控件添加的变量,实现对生产者,消费者,物流移动数量的控制。 Con1_Num ,Pro_Num ,Con2_Num ,Con_Num:控件添加的变量,实现最终的数据统计汇总显示。 Buffer1,buffer2,buffer3:ListBox控件添加的控制变量,用于显示各个buffer中的字符数据内容。4.2线程的设计 PUTTER线程产生随机字符,并放入buffer1中,实现生产者的生产过程。 DWORD W
12、INAPI PUTTER(LPVOID para)/PUT线程其参数为 LPVOID para ,在创建线程时通过P_hThreadsi =CreateThread(NULL,0,PUTTER,(LPVOID)&pthread0,0,&putIDi); 语句,第四个参数传递了结构体参数,将当前对话框窗口类指针传递给线程函数,通过PThread * pthread = (PThread *)para;/规范化参数CpacDlg * dlg = pthread->dlg; 语句来实现对当前对话框窗口中所有参数的调用。 MOVER1,MOVER2,GETTER1,GETTER2
13、线程与PUTTER线程类似。4.3 button按钮的设计 “开始”按钮: 创建每个互斥体,互斥信号以及线程。 void CpacDlg:OnBnClickedButton1()/ TODO: 在此添加控件通知处理程序代码UpdateData(1);g_hMutex1 = :CreateMutex(NULL,FALSE,NULL);/buff1互斥锁 g_hFullItems1 = :CreateSemaphore(NULL,0,SIZE_1,NULL); /buff1信号量 g_hEmptyItems1 = :CreateSemaphore(NULL,SIZE_1, SIZE_1,NULL)
14、; 。 。 /创建PUT线程 for (int i=0;i<Produce_Num;+i)pthread0.dlg = this;pthread0.ptid = i; P_hThreadsi =CreateThread(NULL,0,PUTTER,(LPVOID)&pthread0,0,&putIDi);/if(P_hThreadsi = NULL) MessageBox(TEXT("线程创建错误!"); 。 。 “结束”按钮: 结束每一个线程,并进行数据汇总显示到对话框上。void CpacDlg:OnBnClickedButton2() / TOD
15、O: 在此添加控件通知处理程序代码/UpdateData(1);DWORD KP_Thread10;for(int i=0;i<Produce_Num;i+)TerminateThread(P_hThreadsi,KP_Threadi);。5 编码设计5.1 开发环境Windows7 ,已安装了VS2010。由于本软件是用C+语言开发,所以跨平台性能比较好。本程序使用的主要类、函数,都是自己的写的,用到windows builder插件,用于设计界面。5.2 注意事项1. 编写代码要有良好的格式,有良好的注释,此程序要特别注意 2.注意变量的使用,防止地址引用错误的产生5.3 主要代码设
16、计 PUTTER线程的设计: DWORD WINAPI PUTTER(LPVOID para)/PUT线程PThread * pthread = (PThread *)para;/规范化参数CpacDlg * dlg = pthread->dlg;int i = pthread->ptid;int j=dlg->SPEED;int speed = 1000*j;LARGE_INTEGER nFrequency;/设置随机数的种子 if(:QueryPerformanceFrequency(&nFrequency) / 如果支持高性能精度计数器,则使用其初始化随机种子(
17、微秒级) LARGE_INTEGER nStartCounter; :QueryPerformanceCounter(&nStartCounter); :srand(unsigned)nStartCounter.LowPart); else / 否则使用当前系统时间初始化随机种子(毫秒级) :srand(unsigned)time(NULL); while(true) CString buf; WaitForSingleObject(g_hEmptyItems1,INFINITE); /进行P操作 WaitForSingleObject(g_hMutex1,INFINITE); /产生
18、随机字符(A-Z)char ch;ch = char ( (rand() % 26) + 65 );buf.Format(_T("put->%c"),ch);dlg->buffer1.InsertString(0,buf);dlg->Pro_Num+;/确定生产总数量int buf1c;/确定当前buffer1中的产品数量CString str;buf1c = dlg->buffer1.GetCount();str.Format(_T("%d个"),buf1c);dlg->Buffer_C.SetWindowTextW(st
19、r); /在窗口中显示当前buffer1的数据数量 :Sleep(speed); /速度设置ReleaseMutex(g_hMutex1); /进行V操作ReleaseSemaphore(g_hFullItems1,1,NULL); return 0;MOVER1线程的设计:DWORD WINAPI MOVER1(LPVOID para)/MOVE1线程PThread * pthread = (PThread *) para; /规范化参数CpacDlg * dlg = pthread->dlg;int i = pthread->ptid;int j=(dlg->SPEED)
20、;int speed =1000*j;while(true) WaitForSingleObject(g_hFullItems1,INFINITE); /进行P操作 WaitForSingleObject(g_hEmptyItems2,INFINITE); WaitForSingleObject(g_hMutex1,INFINITE); WaitForSingleObject(g_hMutex2,INFINITE); /将buffer1中的数据移至buffer2中 CString cs; int n; n = dlg->buffer1.GetCount(); dlg->buffer
21、1.GetText(n-1,cs); dlg->buffer1.DeleteString(n-1); CString cc; cc.Format(_T("move1-"); cs = cc + cs; dlg->buffer2.InsertString(0,cs); int buf1c;/确定当前buffer1中的产品数量 CString str; buf1c = dlg->buffer1.GetCount(); str.Format(_T("%d个"),buf1c); dlg->Buffer_C.SetWindowTextW(s
22、tr); /显示当前buffer1中的产品数量 int buf2c;/确定当前buffer2中的产品数量 CString str1; buf2c = dlg->buffer2.GetCount(); str1.Format(_T("%d个"),buf2c); dlg->Buf_C1.SetWindowTextW(str1); /显示当前buffer2中的产品数量 :Sleep(speed); /设置速度 ReleaseMutex(g_hMutex2); /进行V操作 ReleaseMutex(g_hMutex1); ReleaseSemaphore(g_hFul
23、lItems2,1,NULL); ReleaseSemaphore(g_hEmptyItems1,1,NULL); return 0;GETTER1线程的设计:DWORD WINAPI GETTER1(LPVOID para) /GET1线程PThread * pthread = (PThread *)para;/规范化参数CpacDlg * dlg = pthread->dlg;int i = pthread->ptid;int j=(dlg->SPEED);int speed =1000*j ;while(true)WaitForSingleObject(g_hFullI
24、tems2,INFINITE); /进行P操作WaitForSingleObject(g_hMutex2,INFINITE); /移出buffer2中的数据 CString cs; int n; n = dlg->buffer2.GetCount(); dlg->buffer2.GetText(n-1,cs); dlg->buffer2.DeleteString(n-1); dlg->Con1_Num = dlg->Con1_Num + 1; /消费者1消费的产品数量加1 int buf2c; /确定当前buffer2中的产品数量 CString str1; bu
25、f2c = dlg->buffer2.GetCount(); str1.Format(_T("%d个"),buf2c); dlg->Buf_C1.SetWindowTextW(str1); :Sleep(speed); /设置速度ReleaseMutex(g_hMutex2); /进行V操作ReleaseSemaphore(g_hEmptyItems2,1,NULL);return 0; “开始”按钮的设计:void CpacDlg:OnBnClickedButton1()/ TODO: 在此添加控件通知处理程序代码UpdateData(1);g_hMutex1
26、 = :CreateMutex(NULL,FALSE,NULL);/buff1互斥锁 g_hFullItems1 = :CreateSemaphore(NULL,0,SIZE_1,NULL); /buff1信号量 g_hEmptyItems1 = :CreateSemaphore(NULL,SIZE_1, SIZE_1,NULL);g_hMutex2 = :CreateMutex(NULL,FALSE,NULL); g_hFullItems2 = :CreateSemaphore(NULL,0,SIZE_2,NULL); /buff2互斥锁 g_hEmptyItems2 = :CreateSe
27、maphore(NULL,SIZE_2, SIZE_2,NULL);g_hMutex3 = :CreateMutex(NULL,FALSE,NULL); g_hFullItems3 = :CreateSemaphore(NULL,0,SIZE_3,NULL); /buff3互斥锁 g_hEmptyItems3 = :CreateSemaphore(NULL,SIZE_3, SIZE_3,NULL);start = clock(); /获得线程开始时间 /创建PUT线程 for (int i=0;i<Produce_Num;+i)pthread0.dlg = this;pthread0.p
28、tid = i; P_hThreadsi =CreateThread(NULL,0,PUTTER,(LPVOID)&pthread0,0,&putIDi);/if(P_hThreadsi = NULL) MessageBox(TEXT("线程创建错误!"); /创建MOVE1和MOVE2线程 for(int j=0;j<Move1_Num;+j)pthread1.dlg = this;pthread1.ptid = j; M1_hThreadsj =CreateThread(NULL,0,MOVER1,(LPVOID)&pthread1,0,&
29、amp;move1IDj);if(M1_hThreadsj = NULL) MessageBox(TEXT("线程创建错误!"); for(int k=0;k<Move2_Num;+k)pthread2.dlg = this;pthread2.ptid = k; M2_hThreadsk =CreateThread(NULL,0,MOVER2,(LPVOID)&pthread2,0,&move2IDk);if(M2_hThreadsk = NULL) MessageBox(TEXT("线程创建错误!"); /创建GET1和GET2线
30、程for (int m=0;m<Consumer1_Num;+m)pthread3.dlg = this;pthread3.ptid = m; C1_hThreadsm =CreateThread(NULL,0,GETTER1,(LPVOID)&pthread3,0,&get1IDm);if(C1_hThreadsm = NULL) MessageBox(TEXT("线程创建错误!"); for (int n=0;n<Consumer2_Num;+n)pthread4.dlg = this;pthread4.ptid = n; C2_hThrea
31、dsn =CreateThread(NULL,0,GETTER2,(LPVOID)&pthread4,0,&get2IDn);if(C2_hThreadsn = NULL) MessageBox(TEXT("线程创建错误!"); “结束”按钮的设计:void CpacDlg:OnBnClickedButton2() / TODO: 在此添加控件通知处理程序代码/UpdateData(1);DWORD KP_Thread10;for(int i=0;i<Produce_Num;i+)/GetExitCodeThread(P_hThreadsi,&
32、KP_Threadi);TerminateThread(P_hThreadsi,KP_Threadi); /结束线程/ExitThread(KP_Threadi);DWORD KM1_Thread1;for(int i=0;i<Move1_Num;i+)/GetExitCodeThread(M1_hThreadsi,&KM1_Threadi);TerminateThread(M1_hThreadsi,KM1_Threadi);/ExitThread(KM1_Threadi);DWORD KM2_Thread1;for(int i=0;i<Move2_Num;i+)/GetE
33、xitCodeThread(M2_hThreadsi,&KM2_Threadi);TerminateThread(M2_hThreadsi,KM2_Threadi);/ExitThread(KM2_Threadi);DWORD KC1_Thread10;for(int i=0;i<Consumer1_Num;i+)/GetExitCodeThread(C1_hThreadsi,&KC1_Threadi);TerminateThread(C1_hThreadsi,KC1_Threadi);DWORD KC2_Thread10;for(int i=0;i<Consume
34、r2_Num;i+)TerminateThread(C1_hThreadsi,KC2_Threadi);double duration;finish = clock(); /得到线程结束时间duration = double (finish - start)/ CLOCKS_PER_SEC); /得到线程运行总时间CString str4;str4.Format(_T("%2.4f秒"),duration);CLOCK.SetWindowTextW(str4); /输出线程运行总时间CString str;str.Format(_T("%d个"),Pro_Num);Pro_NUM.SetWindowTextW(str); /输出生产者最终生产总数CSt
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年度顶级舞蹈教练专业聘用合同3篇
- 2024实木门生产过程环境监测与治理合同2篇
- 2024年度汽车零部件代加工及销售服务合同2篇
- 2024年度市场推广续签合同申请3篇
- 2024年度智慧城市水资源管理合同2篇
- 2024即开票展示柜销售与服务合同
- 2024年度物业管理公司财务分析合同3篇
- 2024年交通规划专家顾问服务协议范本3篇
- 2024版地下室场地租赁合同附租赁押金及退还规定3篇
- 2024年个人借款给公司合同包括借款用途及还款期限规定3篇
- 《皇帝的新装》课件
- 国家开放大学电大《基础写作》期末题库及答案
- 劳动教育五年级上册北师大版 衣服破了我会补(教案)
- DB3502∕T 139-2024“无陪护”医院服务规范通 用要求
- 期中模拟练习(试题)-2024-2025学年统编版语文二年级上册
- 高职旅游专业《旅游心理学》说课稿
- 人教版九年级历史下册第10课-《凡尔赛条约》和《九国公约》(共31张课件)
- 2023年法律职业资格《客观题卷一》真题及答案
- 教科版 三年级上册科学知识点归纳梳理
- 2024年初级经济师考试经济基础知识真题及答案
- 2024年人教版七年级英语(上册)期末考卷及答案(各版本)
评论
0/150
提交评论