《实验二(1)进程同步》由会员分享,可在线阅读,更多相关《实验二(1)进程同步(13页珍藏版)》请在金锄头文库上搜索。
1、实验二(2)进程同步一、实验目的1、生产者-消费者问题是很典型很具有代表性的进程同步问题,计算机中的诸多同步问题都可抽象为生产者-消费者问题,通过本实验的练习,但愿能加深学生对进程同步问题的结识与理解。2、熟悉VC的使用,培养和提高学生的分析问题、解决问题的能力。二、实验内容及其规定1 实验内容以生产者/消费者模型为根据,创立一种控制台进程,在该进程中创立n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。2 实验规定学习并理解生产者/消费者模型及其同步/互斥规则;设计程序,实现生产者/消费者进程(线程)的同步与互斥;三、实验算法分析1、实验程序的构造图(流程图);开始ProduceWa
2、it BufferWait ProductsConsume结束While produceWhile consume2、数据构造及信号量定义的阐明;(1) CreateThreadl 功能创立一种在调用进程的地址空间中执行的线程l 格式HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParamiter,DWORD dwCreationFlags,Lpdword lpThread );l 参数阐
3、明lpThreadAttributes指向一种LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。dwStackSize定义原始堆栈大小。lpStartAddress指向使用LPTHRAED_START_ROUTINE类型定义的函数。lpParamiter定义一种给进程传递参数的指针。dwCreationFlags定义控制线程创立的附加标志。lpThread保存线程标志符(32位)(2) CreateMutexl 功能创立一种命名或匿名的互斥量对象l 格式HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOO
4、L bInitialOwner,LPCTSTR lpName); bInitialOwner批示目前线程与否立即拥有该互斥量(即马l 参数阐明lpMutexAttributes必须取值NULL。上加锁)。lpName互斥量名称。(3) CreateSemaphorel 功能创立一种命名或匿名的信号量对象l 格式HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName );l 参数阐明lpSemaphoreAt
5、tributes必须取值NULL。lInitialCount信号量的初始值。该值不小于0,但不不小于lMaximumCount指定的最大值。lMaximumCount信号量的最大值。lpName信号量名称。(4) WaitForSingleObject功能使程序处在等待状态,直到信号量hHandle浮现(即其值不小于等于1)或超过规定的等待时间l 格式DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);l 参数阐明hHandle信号量指针。dwMilliseconds等待的最长时间(INFINITE为无限等待)。(5)
6、 ReleaseSemaphorel 功能对指定信号量加上一种指定大小的量。成功执行则返回非0值l 格式BOOL ReleaseSemaphore(HANDLE hSemaphore,LONG lReleaseCount,LPLONG lppreviousCount );l 参数阐明hSemaphore信号量指针。lReleaseCount信号量的增量。lppreviousCount保存信号量目前值。(6) ReleaseMutexl 功能打开互斥锁,即把互斥量加1。成功调用则返回0l 格式BOOL ReleaseMutex(HANDLE hMutex);l 参数阐明hMutex互斥量指针。(
7、7) InitializeCriticalSectionl 功能初始化临界区对象l 格式VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);l 参数阐明lpCriticalSection指向临界区对象的指针。(8) EnterCriticalSection功能等待指定临界区对象的所有权l 格式VOID enterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);l 参数阐明lpCriticalSection指向临界区对象的指针。(9) LeaveCri
8、ticalSectionl 功能释放指定临界区对象的所有权l 格式VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);l 参数阐明lpCriticalSection指向临界区对象的指针4、 重要算法创立生产者和消费者线程for(i =0;iserial;m_delay = (DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC);Sleep(m_delay);/开始祈求生产printf(Producer %2d sends the produce require.n,m_serial);
9、/确认有空缓冲区可供生产,同步将空位置数empty减1;用于生产者和消费者的同步;wait_for_semaphore= WaitForSingleObject(empty_semaphore,-1);/互斥访问下一种可用于生产的空临界区,实现写写互斥;wait_for_mutex = WaitForSingleObject(h_mutex,-1);int ProducePos = FindProducePosition(); ReleaseMutex(h_mutex);/生产者在获得自己的空位置并做上标记后,如下的写操作在生产者之间可以并发;/核心生产环节中,程序将生产者的ID作为产品编号放
10、入,以便消费者辨认;printf(Producer %2d begin to produce at position %2d.n,m_serial,ProducePos);Buffer_CriticalProducePos = m_serial;printf(Producer %2d finish producing :n ,m_serial);printf( position %2d :%3d n ,ProducePos,Buffer_CriticalProducePos);/使生产者写的缓冲区可以被多种消费者使用,实现读写同步;ReleaseSemaphore(h_Semaphorem_s
11、erial,n_Thread,NULL);消费者进程void Consume(void * p)/局部变量声明;DWORDwait_for_semaphore,m_delay;intm_serial,m_requestNum; /消费者的序列号和祈求的数目;intm_thread_requestMAX_THREAD_NUM;/本消费线程的祈求队列; /提取本线程的信息到本地;m_serial = (ThreadInfo*)(p)-serial;m_delay = (DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC);m_requestNum = (Threa
12、dInfo *)(p)-n_request;for (int i = 0;ithread_requesti;Sleep(m_delay);/循环进行所需产品的消费for(i =0;im_requestNum;i+) /祈求消费下一种产品 printf(Consumer %2d request to consume %2d productn,m_serial,m_thread_requesti); /如果相应生产者没有生产,则等待;如果生产了,容许的消费者数目-1;实现了读写同步; wait_for_semaphore=WaitForSingleObject(h_Semaphorem_thread_requesti,-1); /查询所需产品放到缓冲区的号 int BufferPos=FindBufferPosition(m_thread_requesti); /开始进行具体缓冲区的消费解决,读和读在该缓冲区上仍然是互斥的; /进入临界区后执行消费动作;并在完毕本次祈求后,告知此外的消费者本处祈求已 /经满足;同步如果相应的产品使用完毕,就做相应解决;并给出相应动作的界面提 /示;该相应解决指将相应缓冲区清空,并增长代表空缓冲区的信号量; EnterCriticalSection(&PC_Crit