1、生产者与消费者实验报告班别:2006 软件技术 3 班 学号:200630481228 姓名:赖永周实验目的:掌握线程创建和终止,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的通信。实验内容:点“创建线程” 按钮,创建三个生产者线程( P1,P2,P3)和两个消费者线程(C1, C2) ,生产者和消费者线程共享一个长度为 2KB 的环型公共缓冲区,生产者向其中投放消息,消费者从中取走消息。只要缓冲区未满,生产者可将消息送入缓冲区;只要缓冲区未空,消费者可从缓冲区取走一个消息。每个生产者每隔 n 秒(n 用随机数产生,1 到 10 秒之间,间隔不固定)生产一个消息加入缓冲区,并把消
2、息产生时间和内容记录在列表框中。P1 每次生产的数据为 26 个大写字母, P2 每次生产的数据为 26 个小写字母,P3 每次生产的数据为 10 个数字。每个消费者每隔 n 秒(n 用随机数产生,1 到 5 秒之间,间隔不固定)从缓冲区取走一个消息。每消费一个消息需要将消费时间和消息内容记录在列表框中。同时用一个列表框记录实时缓冲区中的消息内容.当用户按结束按钮时结束 5 个线程。实验设计方法:1. 实验同步的设计方法:实验中使用 WinAPI 函数创建了一个互斥量 h_Mutex,两个信号量 bufferFullSemaphore 用以录满的信号, bufferEmptySemaphore
3、 用以记录空的信号.其中用到的函数方法: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)DWORD
4、 WINAPI Producter3(LPVOID pthread)2 个消费者入口函数:DWORD WINAPI Consumer1(LPVOID pthread)DWORD WINAPI Consumer2(LPVOID pthread)在每个入口函数中,使用函数:DWORD WINAPI WaitForSingleObject(_in HANDLE hHandle,_in DWORD dwMilliseconds); BOOL WINAPI ReleaseSemaphore(_in HANDLE hSemaphore,_in LONG lReleaseCount,_out LPLONG
5、lpPreviousCount);BOOL WINAPI ReleaseMutex(_in HANDLE hMutex);对互斥量以及相应的信号量进行管理,使线程能够同步运行.然后在主函数中使用函数:HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParamiter,DWORD dwCreationFlags,Lpdword lpThread );分别为每个生产者和消费者创建线程.最后,使用
6、函数BOOL WINAPI TerminateThread(_in_out HANDLE hThread,_in DWORD dwExitCode);结束所有线程.2. 实验数据的定义:实验中定义了一个线程结构体,其中封装了 CListBox 类指针,即列表框的所有操作.线程结构体定义如下:typedef struct ThreadinfoCListBox*pList;thread,*lpthread;实验中使用的缓冲区定义为循环队列用以记录缓冲区中的消息内容,其定义如下:const int BUFFER_SIZE =5; /缓冲区长度CString bufferBUFFER_SIZE = “
7、0“; /缓冲区循环队列int in = 0; /用与追踪产品进缓冲区时的缓冲区数组下标int out = 0;实验中的消息定义统一为 CString 类.3. 实验设计思想和设计流程本程序是基于 MFC 对话框结构的应用程序 .设计思想:实验调用 WinAPI 函数,创建多线程的同步方法 ,把列表框封装在新的结构体类作为入口函数传递参数的指针,用以指定不同的列表框显示对应不同的内容.设计流程:如图:CMFCThreadDlgthread thread1;thread thread2;HANDLE hThread1;HANDLE hThread2;HANDLE hThread3;HANDLE
8、hThread4;HANDLE hThread5;CListBoxm_ProList;CListBoxm_ConList;void OnCancle()void OnClearUp()void OnCreateThread()void OnDestroyThread()bufferint in,out;ThreadinfoCListBox*pListDWORD WINAPI Producter1(LPVOID pthread)DWORD WINAPI Producter1(LPVOID pthread)DWORD WINAPI Producter1(LPVOID pthread)DWORD W
9、INAPI Consumer1(LPVOID pthread)DWORD WINAPI Consumer1(LPVOID pthread)图 1由图 1 知,CMFCThfreadDlg 依赖 buffer,Threadinfo 和生产者与消费者的 5 个接口函数.函数说明及部分代码:void OnCancle() /退出void OnClearUp() /清空列表框以及缓冲void CMFCThreadDlg:OnCreateThread() /创建线程/ TODO: Add your control notification handler code hereGetDlgItem(IDC_
10、DESTROY_THREAD)-EnableWindow(true);DWORD code;control=true;DWORD ProducterID3,ConsumerID2;thread1.pList= /指向不同的列表框控件thread2.pList=h_Mutex = CreateMutex(NULL,false,NULL); /创建互斥量/创建信号量bufferFullSemaphore = CreateSemaphore(NULL,BUFFER_SIZE,BUFFER_SIZE,NULL); bufferEmptySemaphore = CreateSemaphore(NULL,
11、0,BUFFER_SIZE,NULL);if(!GetExitCodeThread(hThread1,if(!GetExitCodeThread(hThread2,if(!GetExitCodeThread(hThread3,if(!GetExitCodeThread(hThread4,if(!GetExitCodeThread(hThread5,void OnDestroyThread() /销毁线程DWORD WINAPI Producter1(LPVOID pthread) /生产者入口函数int t;CTime c_Time;CString s_Time;lpthread temp=(
12、lpthread)pthread; /参数指针转换CString str=“ P1:“;while(control)t=1000*(rand()%9+1); /随机时间(110 秒)c_Time=CTime:GetCurrentTime(); /获取当前系统时间s_Time=c_Time.Format(“%H:%M:%S “); /格式化时间WaitForSingleObject(bufferFullSemaphore,INFINITE); /等待信号量 WaitForSingleObject(h_Mutex,INFINITE); /等待互斥量bufferin=Z-rand()%26; /随机
13、生成 26 个大写字母temp-pList-AddString(s_Time+str+bufferin); /在指定列表框添加内容m_Buffer.AddString(bufferin); /在缓冲区列表框添加内容in=(in+1)%BUFFER_SIZE; /循环队列指针加 1Sleep(t); /函数阻塞时间ReleaseMutex(h_Mutex); /释放互斥量ReleaseSemaphore(bufferEmptySemaphore,1,NULL); /释放信号量 return true;DWORD WINAPI Consumer1(LPVOID pthread) /消费者入口函数i
14、nt t,flag=0;CTime c_Time;CString s_Time;lpthread temp=(lpthread)pthread; /参数指针转换CString str=“ C1:“;while(control)t=1000*(rand()%4+1); /随机时间(15 秒)c_Time=CTime:GetCurrentTime(); /获取当前系统时间s_Time=c_Time.Format(“%H:%M:%S “); /格式化时间WaitForSingleObject(bufferEmptySemaphore,INFINITE); /等待信号量WaitForSingleObj
15、ect(h_Mutex,INFINITE); /等待互斥量temp-pList-AddString(s_Time+str+bufferout); /相应列表框添加内容/缓冲区列表框寻找相应内容删去if(flag=m_Buffer.FindString(0,(LPCTSTR)bufferout)!=CB_ERR) m_Buffer.DeleteString(flag);bufferout=“0“; /缓冲区内空置空out=(out+1)%BUFFER_SIZE; /循环队列加 1Sleep(t); /函数阻塞时间ReleaseMutex(h_Mutex); /释放互斥量ReleaseSemaphore(bufferFullSemaphore,1,NULL); /释放信号量return true;4. 程序运行结果:5. 实验问题与体会:实验的消息内容并没有严格按照实验要求进行设计,从而缓冲区的设置仍有待改进.通过这次的实验,对 windows 多线程编程有了一定的理解.同时在实验过程中,明白了多线程编程同步对象的实现方法必须十分小心,以免造成死锁与共享内容错误操作.
Copyright © 2018-2021 Wenke99.com All rights reserved
工信部备案号:浙ICP备20026746号-2
公安局备案号:浙公网安备33038302330469号
本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。