logo资料库

操作系统生产者消费者问题实验报告.doc

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
HUNAN UNIVERSITY
生产者-消费者问题
实习五 生产者-消费者问题实现
HUNAN UNIVERSITY 操作系统原理 实验报告 实 验 题 目 : 生产者-消费者问题 学 生 姓 名 : 学 生 学 号 : 靳清凯 20070810610 专 业 班 级 : 计算机科学与技术六班 同 组 成 员 : 蒋贵华 喻玲瑶 实 验 地 点 : 计通院实验中心 实 验 时 间 : 11.29 指 导 老 师 : 肖德贵、彭李翔
操 作 系 统 原 理 实 验 报 告 实习五 生产者-消费者问题实现 一、实验目的 1.熟悉临界资源、信号量及 PV 操作的定义与物理意义; 2.了解进程通信的方法; 3.掌握进程互斥与进程同步的相关知识; 4.掌握用信号量机制解决进程之间的同步与互斥问题; 5.实现生产者-消费者问题,深刻理解进程同步问题。 二、实验环境 VC++6.0 三、实验内容 经典同步问题:生产者—消费者,具体要求如下: 1.一个大小为 5 缓冲区,初始状态为空; 2.3 生产者,随机等待一段时间,往缓冲区中添加数据,若缓冲区已满,等待消费者取走数据 之后再添加,重复 5 次。 3.2 个消费者,随机等待一段时间,从缓冲区中读取数据,若缓冲区为空,等待生产者添加数 据之后再读取,重复 5 次。 Buffer(大小为 5) 生产者 ……… 消费者 模拟程序的程序流程图如下所示: 1.主程序流程图: 1
操 作 系 统 原 理 实 验 报 告 入口 初始化信号量 分配共享内存 创建生产者与消费者进程 释放内存 退出 2.生产者进程流程图: 2
操 作 系 统 原 理 实 验 报 告 3.消费者进程流程图: 四、实验结果(含程序、数据记录及分析、实验总结等) 实验设计方法: 1. 实验同步的设计方法: 实验中使用 WinAPI 函数创建了一个互斥量 h_Mutex,两个信号量 bufferFullSemaphore 用以录满的信 号, bufferEmptySemaphore 用以记录空的信号. 其中用到的函数方法: h_Mutex = CreateMutex(NULL,false,NULL); bufferFullSemaphore = CreateSemaphore(NULL,BUFFER_SIZE,BUFFER_SIZE,NULL); bufferEmptySemaphore = CreateSemaphore(NULL,0,BUFFER_SIZE,NULL); 同时定义了: 3 个生产者入口函数为: DWORD WINAPI Producter1(LPVOID pthread) DWORD WINAPI Producter2(LPVOID pthread) 3
操 作 系 统 原 理 实 验 报 告 DWORD WINAPI Producter3(LPVOID pthread) 2 个消费者入口函数: DWORD WINAPI Consumer1(LPVOID pthread) DWORD WINAPI Consumer2(LPVOID pthread) 在每个入口函数中,使用函数: DWORD WINAPI WaitForSingleObject( __in __in HANDLE hHandle, DWORD dwMilliseconds ); BOOL WINAPI ReleaseSemaphore( __in __in __out HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount ); BOOL WINAPI ReleaseMutex( __in HANDLE hMutex ); 对互斥量以及相应的信号量进行管理,使线程能够同步运行. 然后在主函数中使用函数: HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParamiter, DWORD dwCreationFlags, Lpdword lpThread ); 分别为每个生产者和消费者创建线程. 最后,使用函数 BOOL WINAPI TerminateThread( __in_out __in HANDLE hThread, DWORD dwExitCode ); 结束所有线程. 2. 实验数据的定义: 实验中定义了一个线程结构体,其中封装了 CListBox 类指针,即列表框的所有操作. 线程结构体定义如下: typedef struct Threadinfo{ CListBox*pList; }thread,*lpthread; 实验中使用的缓冲区定义为循环队列用以记录缓冲区中的消息内容,其定义如下: const int BUFFER_SIZE =5; CString buffer[BUFFER_SIZE] = {"0"}; int in = 0; //用与追踪产品进缓冲区时的缓冲区数组下标 //缓冲区长度 //缓冲区循环队列 4
操 作 系 统 原 理 实 验 报 告 int out = 0; 实验中的消息定义统一为 CString 类. 3. 实验设计思想和设计流程 本程序是基于 MFC 对话框结构的应用程序. 设计思想: 实验调用 WinAPI 函数,创建多线程的同步方法,把列表框封装在新的结构体类作为入口函数传递参数 的指针,用以指定不同的列表框显示对应不同的内容. 设计流程: 如图: <> CMFCThreadDlg DWORD WINAPI Producter1(LPVOID pthread) DWORD WINAPI Producter1(LPVOID pthread) DWORD WINAPI Producter1(LPVOID pthread) DWORD WINAPI Consumer1(LPVOID pthread) DWORD WINAPI Consumer1(LPVOID pthread) buffer int in,out; thread thread1; thread thread2; HANDLE hThread1; HANDLE hThread2; HANDLE hThread3; HANDLE hThread4; HANDLE hThread5; CListBoxm_ProList; CListBoxm_ConList; void OnCancle() void OnClearUp() void OnCreateThread() void OnDestroyThread() Threadinfo CListBox*pList 由图 1 知,CMFCThfreadDlg 依赖 buffer,Threadinfo 和生产者与消费者的 5 个接口函数. 图 1 5
操 作 系 统 原 理 实 验 报 告 实验代码: 创建线程: void CMFCThreadDlg::OnCreateThread() { // TODO: Add your control notification handler code here GetDlgItem(IDC_DESTROY_THREAD)->EnableWindow(true); DWORD code; control=true; DWORD ProducterID[3],ConsumerID[2]; thread1.pList=&m_ProList; thread2.pList=&m_ConList; h_Mutex = CreateMutex(NULL,false,NULL); bufferFullSemaphore = CreateSemaphore(NULL,BUFFER_SIZE,BUFFER_SIZE,NULL); bufferEmptySemaphore = CreateSemaphore(NULL,0,BUFFER_SIZE,NULL); if(!GetExitCodeThread(hThread1,&code)||(code!=STILL_ACTIVE)){ 6
操 作 系 统 原 理 实 验 报 告 hThread1=CreateThread(NULL,0,Producter1,&thread1,0,&ProducterID[0]); } if(!GetExitCodeThread(hThread2,&code)||(code!=STILL_ACTIVE)){ hThread2=CreateThread(NULL,0,Producter2,&thread1,0,&ProducterID[1]); } if(!GetExitCodeThread(hThread3,&code)||(code!=STILL_ACTIVE)){ hThread3=CreateThread(NULL,0,Producter3,&thread1,0,&ProducterID[2]); } if(!GetExitCodeThread(hThread4,&code)||(code!=STILL_ACTIVE)){ hThread4=CreateThread(NULL,0,Consumer1,&thread2,0,&ConsumerID[0]); } if(!GetExitCodeThread(hThread5,&code)||(code!=STILL_ACTIVE)){ hThread5=CreateThread(NULL,0,Consumer2,&thread2,0,&ConsumerID[1]); } } 结束线程: void CMFCThreadDlg::OnDestroyThread() { // TODO: Add your control notification handler code here DWORD code; control=false; if(GetExitCodeThread(hThread1,&code)&&(code==STILL_ACTIVE)){ TerminateThread(hThread1,0); CloseHandle(hThread1); } if(GetExitCodeThread(hThread2,&code)&&(code==STILL_ACTIVE)){ TerminateThread(hThread2,0); CloseHandle(hThread2); } if(GetExitCodeThread(hThread3,&code)&&(code==STILL_ACTIVE)){ 7
分享到:
收藏