资源预览内容
第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
第9页 / 共18页
第10页 / 共18页
亲,该文档总共18页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
操作系统课程设计报告题目:生产者与消费者问题 班级: $ 学号: 0804010214 姓名: $ 指导教师$2010-1-13一、题目(生产者与消费者问题)1.课程设计题目分析题目分析:生产者-消费者问题是一个经典的进程同步问题,该问题最早由 Dijkstra 提出,用以演示他提出的信号量机制。要求设计在同一个进程地址空间内执行的两个进程。生产者进程生产物品,然后将物品放置在一个空缓冲区中供消费者进程消费。消费者进程从缓冲区中获得物品,然后释放缓冲区。当生产者进程生产物品时,如果没有空缓冲区可用,那么生产者进程必须等待消费者进程释放出一个空缓冲区。当消费者进程消费物品时,如果没有满的缓冲区,那么消费者进程将被阻塞,直到新的物品被生产出来。 功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放 数据、取数据等过程。键盘输入进程数和缓冲区数目,可调度生产者、消费者的活动及显示 进程的当前状态。 为实现进程互斥的进入自己的临界区,所有同步机制都应遵循以下四条准则:(1)空 闲让进, (2)忙着等待, (3)有限等待(4)让权等待。2.数据结构(1) CreateThread 功能创建一个在调用进程的地址空间中执行的线程 格式 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParamiter, DWORD dwCreationFlags, Lpdword lpThread ); 参数说明lpThreadAttributes指向一个 LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。 dwStackSize定义原始堆栈大小。 lpStartAddress指向使用 LPTHRAED_START_ROUTINE 类型定义的函数。 lpParamiter定义一个给进程传递参数的指针。 dwCreationFlags定义控制线程创建的附加标志。 lpThread保存线程标志符(32 位) (2) CreateMutex 功能创建一个命名或匿名的互斥量对象 格式 HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName); 参数说明lpMutexAttributes必须取值 NULL。 bInitialOwner指示当前线程是否马上拥有该互斥量(即马上加锁)。 lpName互斥量名称。 (3) CreateSemaphore 功能创建一个命名或匿名的信号量对象 格式 HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,LONG lMaximumCount,LPCTSTR lpName ); 参数说明lpSemaphoreAttributes必须取值 NULL。 lInitialCount信号量的初始值。该值大于 0,但小于 lMaximumCount 指定的最大值。 lMaximumCount信号量的最大值。 lpName信号量名称。 (4) WaitForSingleObject 功能使程序处于等待状态,直到信号量 hHandle 出现(即其值大于等于 1)或超过规 定的等待时间 格式 DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); 参数说明hHandle信号量指针。 dwMilliseconds等待的最长时间(INFINITE 为无限等待)。 (5) ReleaseSemaphore 功能对指定信号量加上一个指定大小的量。成功执行则返回非 0 值 格式 BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lppreviousCount ); 参数说明hSemaphore信号量指针。 lReleaseCount信号量的增量。 lppreviousCount保存信号量当前值。 (6) ReleaseMutex 功能打开互斥锁,即把互斥量加 1。成功调用则返回 0 格式 BOOL ReleaseMutex(HANDLE hMutex); 参数说明hMutex互斥量指针。 (7) InitializeCriticalSection 功能初始化临界区对象 格式 VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 参数说明lpCriticalSection指向临界区对象的指针。 (8) EnterCriticalSection 功能等待指定临界区对象的所有权 格式VOID enterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 参数说明lpCriticalSection指向临界区对象的指针。 (9) LeaveCriticalSection 功能释放指定临界区对象的所有权 格式 VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 参数说明lpCriticalSection指向临界区对象的指针。3.流程图ProduceWait BufferWait ProductsConsume结束While produceWhile consumeBegin4.所用技术和实现功能(1)所用技术:应用进程同步技术信号量,以生产者/消费者模型为依据,在Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。应用信号量机制实现生产者与消费者进程互斥的访问缓冲区,缓冲区为一个循环队列。(2)实现功能:键盘输入进程数和缓冲区数目,可调度生产者、消费者的活动及显示进程的当前状态。5、设计结论和心得(1)结论:在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品 放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲 区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线 程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程 将被阻塞,直到新的物品被生产出来。 (2)心得:通过课程设计,进一步学习并理解生产者/消费者模型及其同步互斥规则,学习 了解了 windows 同步对象及其特性,熟悉实验环境,掌握有关 API 的使用方法,同时熟悉对 vc 的使用,提高了分析问题以及解决问题的能力,通过学习相关知识,扩展了知识面。6.课程设计源代码;#include #include #include #include #include/定义常量; /此程序允许的最大临界区数; #define MAX_BUFFER_NUM 10 /秒到微秒的乘法因子; #define INTE_PER_SEC 1000 /本程序允许的生产和消费线程的总数; #define MAX_THREAD_NUM 64/定义一个结构,记录在测试文件中指定的每一个线程的参数 struct ThreadInfo intserial;/线程序列号 char entity; /是 P 还是 C doubledelay;/线程延迟 intthread_requestMAX_THREAD_NUM; /线程请求队列 intn_request;/请求个数 ;/全局变量的定义/临界区对象的声明,用于管理缓冲区的互斥访问; CRITICAL_SECTIONPC_CriticalMAX_BUFFER_NUM;int Buffer_CriticalMAX_BUFFER_NUM; /缓冲区声明,用于存放产品; HANDLE h_ThreadMAX_THREAD_NUM; /用于存储每个线程句柄的数组; ThreadInfoThread_InfoMAX_THREAD_NUM; /线程信息数组; HANDLEempty_semaphore; /一个信号量; HANDLEh_mutex; /一个互斥量; DWORDn_Thread = 0; /实际的线程的数目; DWORDn_Buffer_or_Critical; /实际的缓冲区或者临界区的数目; HANDLEh_SemaphoreMAX_THREAD_NUM; /生产者允许消费者开始消费的信号量;/生产消费及辅助函数的声明 void Produce(void *p); void Consume(void *p); bool IfInOtherRequest(int); int FindProducePositon(); int FindBufferPosition(int);int main(void) /声明所需变量; DWORDwait_for_all; ifstream inFile;/初始化缓冲区; for(int i=0;i n_Buffer_or_Critical; inFile.get(); printf(“输入文件是:n“); /回显获得的缓冲区的数目信息; printf(“%d n“,(int) n_Buffer_or_Critical); /提取每个线程的信息到相应数据结构中;while(inFile) inFile Thread_Infon_Thread.serial; inFile Thread_Infon_Thread.entity; inFile Thread_Infon_Thread.delay; char c; inFile.get(c); while(c!=ninFile.get(c); n_Thread+; /回显获得的线程信息,便于确认正确性; for(j=0;jserial; m_delay = (DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC);Sleep(m_delay); /开始请求生产 printf(“Producer %2d sends the produce require.n“,m_serial);/确认有空缓冲区可供生产,同时将空位置数 empty 减 1;用于生产者和消费者的同步;wait_for_semaphore= WaitForSingleObject(empty_semaphore,-1);/互斥访问下一个可用于生产的空临界区,实现写写互斥; wait_for_mutex = WaitForSingleObject(h_mutex,-1); int ProducePos = FindProducePosition();ReleaseMutex(h_mutex);/生产者在获得自己的空位置并做上标记后,以下的写操作在生产者之间可以并发; /核心生产步骤中,程序将生产者的 ID 作为产品编号放入,方便消费者识别; printf(“Produ
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号