定时器与多线程 SetTimer and Multi-Thread 每个线程独立使用一个定时器
生产者——消费者 模拟程序,需求如下:
所以我的解决方案如下:
/* 更改定时器的消息 */ #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; }
---------------------------------------------------------------------------
UINT_PTR hTimer = 0; //定时器消息处理函数 VOID __stdcall TimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime) { KillTimer(NULL,hTimer); MessageBox(NULL,"Speak in Timer!",":)",MB_OK); } //线程函数 DWORD __stdcall ThreadFun(void *) { MSG msg; PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE); hTimer = SetTimer(NULL,0,10,(TIMERPROC)TimerProc); while(!PeekMessage(&msg,NULL,WM_TIMER,WM_USER+1,PM_NOREMOVE)) { OutputDebugString("Not peek message\r\n"); Sleep(100); } if(msg.message == (WM_USER+1)) { //收到主线程发来的消息 OutputDebugString("Rec message\r\n"); } else { //收到定时器消息,派送之 OutputDebugString("what message\r\n"); DispatchMessage(&msg); } return 0; } //创建线程代码: DWORD dwThreadId; HANDLE hThread = NULL; hThread = CreateThread(NULL,0,ThreadFun,NULL,0,&dwThreadId); if (hThread == NULL) { MessageBox("CreateThread failed.", "main", MB_OK ); } else { OutputDebugString("prepare post message\r\n"); Sleep(1000);//等待线程创建好了 PostThreadMessage(dwThreadId,WM_USER+1,0,0);//给线程发消息 OutputDebugString("Post message ok\r\n"); CloseHandle( hThread ); }
这是MFC的CWinThread类的实现。 首先创建一个线程 _beginthread(MainThread, DEFAULT_STACK_SIZE, NULL);
然后在MainThread中创建一个看不见的窗口(伪窗口):
WNDCLASS wcl; HWND hWnd = NULL; memset(&wcl,0,sizeof(wcl)); if (lpfnWndProc == NULL) { return NULL; /*失败*/ } /*register class*/ wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.hbrBackground = NULL; wcl.hCursor = NULL; wcl.hIcon = NULL; wcl.hInstance = NULL; wcl.lpfnWndProc = MainWindowProc; wcl.lpszClassName = szWndName; wcl.lpszMenuName = NULL; wcl.style = CS_VREDRAW; if (RegisterClass(&wcl) == 0) { return NULL; } /*create window*/ hWnd = CreateWindow(szWndName,NULL,WS_POPUP,0,0, CW_USEDEFAULT,CW_USEDEFAULT, NULL,NULL,NULL,NULL); /*进入消息循环*/ do { ret = GetMessage(&msg,NULL,0,0); if (ret > 0) { DispatchMessage(&msg); } }while(ret > 0); DestroySTUNServerWindow(szWndName, s_hSTUNServerWnd); 最后可以在MainWindowProc中处理你的消息了: LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { default: return DefWindowProc(hWnd,uMsg,wParam,lParam); } return 0; }