6:生产者消费者问题

上传人:第*** 文档编号:35002594 上传时间:2018-03-06 格式:DOC 页数:7 大小:100.50KB
返回 下载 相关 举报
6:生产者消费者问题_第1页
第1页 / 共7页
6:生产者消费者问题_第2页
第2页 / 共7页
6:生产者消费者问题_第3页
第3页 / 共7页
6:生产者消费者问题_第4页
第4页 / 共7页
6:生产者消费者问题_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《6:生产者消费者问题》由会员分享,可在线阅读,更多相关《6:生产者消费者问题(7页珍藏版)》请在金锄头文库上搜索。

1、生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产 品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者 之间设置一个具有多个缓冲区的缓冲池,生产者将它生产的产品放入一个缓冲区中,消费 者可以从缓冲区中取走产品进行消费,显然生产者和消费者之间必须保持同步,即不允许 消费者到一个空的缓冲区中取产品,也不允许生产者向一个已经放入产品的缓冲区中再次 投放产品。这个生产者消费者题目不仅常用于操作系统的课程设计,也常常在程序员和软件设计师 考试中出现。并且在计算机考研的专业课考试中也是一个非常热门的问题。因此现在就针 对这个问题进行详细深入的解答。首

2、先来简化问题,先假设生产者和消费者都只有一个,且缓冲区也只有一个。这样情况 就简便多了。第一从缓冲区取出产品和向缓冲区投放产品必须是互斥进行的。可以用关键段和互斥 量来完成。第二生产者要等待缓冲区为空,这样才可以投放产品,消费者要等待缓冲区不为空, 这样才可以取出产品进行消费。并且由于有二个等待过程,所以要用二个事件或信号量来 控制。 /1生产者1消费者1缓冲区 /使用二个事件,一个表示缓冲区空,一个表示缓冲区满。 /再使用一个关键段来控制缓冲区的访问 #include #include #include /设置控制台输出颜色 BOOL SetConsoleColor(WORD wAttrib

3、utes) HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (hConsole = INVALID_HANDLE_VALUE) return FALSE; return SetConsoleTextAttribute(hConsole, wAttributes); const int END_PRODUCE_NUMBER = 10; /生产产品个数 int g_Buffer; /缓冲区 /事件与关键段 CRITICAL_SECTION g_cs; HANDLE g_hEventBufferEmpty, g_hEventBufferFu

4、ll; /生产者线程函数 unsigned int _stdcall ProducerThreadFun(PVOID pM) for (int i = 1; i #include #include /设置控制台输出颜色 BOOL SetConsoleColor(WORD wAttributes) HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); if (hConsole = INVALID_HANDLE_VALUE) return FALSE; return SetConsoleTextAttribute(hConsole, wAttribu

5、tes); const int END_PRODUCE_NUMBER = 8; /生产产品个数 const int BUFFER_SIZE = 4; /缓冲区个数 int g_BufferBUFFER_SIZE; /缓冲池 int g_i, g_j; /信号量与关键段 CRITICAL_SECTION g_cs; HANDLE g_hSemaphoreBufferEmpty, g_hSemaphoreBufferFull; /生产者线程函数 unsigned int _stdcall ProducerThreadFun(PVOID pM) for (int i = 1; i = END_PRO

6、DUCE_NUMBER; i+) /等待有空的缓冲区出现 WaitForSingleObject(g_hSemaphoreBufferEmpty, INFINITE); /互斥的访问缓冲区 EnterCriticalSection( g_Bufferg_i = i;printf(“生产者在缓冲池第%d个缓冲区中投放数据%dn“, g_i, g_Bufferg_i); g_i = (g_i + 1) % BUFFER_SIZE; LeaveCriticalSection( /通知消费者有新数据了 ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL);

7、 printf(“生产者完成任务,线程结束运行n“); return 0; /消费者线程函数 unsigned int _stdcall ConsumerThreadFun(PVOID pM) while (true) /等待非空的缓冲区出现 WaitForSingleObject(g_hSemaphoreBufferFull, INFINITE); /互斥的访问缓冲区 EnterCriticalSection( SetConsoleColor(FOREGROUND_GREEN); printf(“ 编号为%d的消费者从缓冲池中第%d个缓冲区取出数据%dn“, GetCurrentThread

8、Id(),g_j, g_Bufferg_j); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); if (g_Bufferg_j = END_PRODUCE_NUMBER)/结束标志 LeaveCriticalSection( /通知其它消费者有新数据了(结束标志) ReleaseSemaphore(g_hSemaphoreBufferFull, 1, NULL); break; g_j = (g_j + 1) % BUFFER_SIZE; LeaveCriticalSection( Sleep(50);

9、 /some other work to do ReleaseSemaphore(g_hSemaphoreBufferEmpty, 1, NULL); SetConsoleColor(FOREGROUND_GREEN); printf(“ 编号为%d的消费者收到通知,线程结束运行n“, GetCurrentThreadId(); SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); return 0; int main() printf(“生产者消费者问题 1生产者2消费者4缓冲区n“); Initializ

10、eCriticalSection( /初始化信号量,一个记录有产品的缓冲区个数,另一个记录空缓冲区个数. g_hSemaphoreBufferEmpty = CreateSemaphore(NULL, 4, 4, NULL); g_hSemaphoreBufferFull = CreateSemaphore(NULL, 0, 4, NULL); g_i = 0; g_j = 0; memset(g_Buffer, 0, sizeof(g_Buffer); const int THREADNUM = 3; HANDLE hThreadTHREADNUM; /生产者线程 hThread0 = (H

11、ANDLE)_beginthreadex(NULL, 0, ProducerThreadFun, NULL, 0, NULL); /消费者线程 hThread1 = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL); hThread2 = (HANDLE)_beginthreadex(NULL, 0, ConsumerThreadFun, NULL, 0, NULL); WaitForMultipleObjects(THREADNUM, hThread, TRUE, INFINITE); for (int i = 0; i THREADNUM; i+) CloseHandle(hThreadi); /销毁信号量和关键段 CloseHandle(g_hSemaphoreBufferEmpty); CloseHandle(g_hSemaphoreBufferFull); DeleteCriticalSection( return 0; 运行结果:

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 教学课件 > 初中课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号