前几天,一个同学让我帮他做操作系统课程里的 生产者——消费者 模拟程序,需求如下:
希望各位大侠提供一个更好的解决方案。
将生产者和消费者模拟算法封装在一个动态链接库中,主程序调用相关函数。生产者放入产品和消费者取走产品的速度可调节。
分别用循环队列和栈实现。
一般模拟这个算法都是生产这,消费者各开一个线程,同步访问一个共享缓冲区。但是需求要求能调节速度,我的思路是在
每个线程里单独创建一个定时器,但是Windows下定时器特性是:
每隔定时时间,Windows系统放入一个 WM_TIMER 消息到应用程序的消息队列中。
所以我的解决方案如下:
- /* 更改定时器的消息 */
- #define WM_SETTIMER WM_USER + 100
- /* 生产者线程函数 */
- DWORD WINAPI ProducerFunc(LPVOID lpParameter)
- {
- MSG msg;
- UINT producerTimerId;
- /* Create a message queue for this thread */
- PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
- producerTimerId = SetTimer(NULL, 0, g_uProducerTimer, NULL);
- while(GetMessage(&msg, NULL, 0, 0))
- {
- if(msg.message == WM_TIMER)
- {
- WaitForSingleObject(g_hEmptySemaphore, INFINITE);
- WaitForSingleObject(g_hMutex, INFINITE);
- Producer();
- ReleaseMutex(g_hMutex);
- ReleaseSemaphore(g_hFullSemaphore, 1, NULL);
- }
- else if(msg.message == WM_SETTIMER)
- {
- KillTimer(NULL, producerTimerId);
- producerTimerId = SetTimer(NULL, 0, g_uProducerTimer, NULL);
- }
- else
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- KillTimer(NULL, producerTimerId);
- return 0;
- }
- /* 消费者线程函数 */
- DWORD WINAPI ConsumerFunc(LPVOID lpParameter)
- {
- MSG msg;
- UINT consumerTimerId;
- PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
- consumerTimerId = SetTimer(NULL, 0, g_uConsumerTimer, NULL);
- while(GetMessage(&msg, NULL, 0, 0))
- {
- if(msg.message == WM_TIMER)
- {
- WaitForSingleObject(g_hFullSemaphore, INFINITE);
- WaitForSingleObject(g_hMutex, INFINITE);
- Consumer();
- ReleaseMutex(g_hMutex);
- ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);
- }
- else if(msg.message == WM_SETTIMER)
- {
- KillTimer(NULL, consumerTimerId);
- consumerTimerId = SetTimer(NULL, 0, g_uConsumerTimer, NULL);
- }
- else
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- KillTimer(NULL, consumerTimerId);
- return 0;
- }
完整的源代码在这里: