线程消息通信

来源:互联网 发布:python进阶书籍 知乎 编辑:程序博客网 时间:2024/06/06 02:47

           线程间的消息通信主要采用PostThreadMessage函数来实现,主线程通过该函数来实现消息的发送,副线程则采用消息循环机制来驱动程序,当副线程无GUI时,就不能调用TranslateMessage,DispatchMessage之类的函数,因为该函数无法将消息派发至对应的窗口,这样的话,对于副线程中的MessageBox等有关窗口的消息就不能捕获,转而必须通过线程级别的钩子来实现消息处理。另外,在处理消息时,注意副线程由于无GUI导致消息队列的初始化可能会推迟,而需要调用PeekMessage函数来强制消息队列的创建,同时来通知主线程消息队列已创建完成。具体实现代码如下:

#include "stdafx.h"#define TM_CONSUMER  WM_APP + 0x100#define TM_PRODUCER  WM_APP + 0x101#ifndef PTHREAD_STARTtypedef unsigned (__stdcall *PTHREAD_START) (void *);#endif#ifndef chBEGINTHREADEX#define chBEGINTHREADEX(psa,cbStackSize,pfnStartAddr,\pvParam, fdwCreate,pdwThreadID)                  \((HANDLE) _beginthreadex(                        \(void *)psa,                                     \(unsigned)(cbStackSize),                         \(PTHREAD_START) (pfnStartAddr),                  \(void *)(pvParam),                               \(unsigned)(fdwCreate),                           \(unsigned *)(pdwThreadID)))#endifDWORD WINAPI ThreadRun(PVOID pvParam){MSG msg;BOOL bRet;HANDLE hEvent = (HANDLE)pvParam;PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_REMOVE);SetEvent(hEvent);while((bRet = GetMessage(&msg,NULL,0,0)) != 0) {if(bRet == -1) {printf("Fail to GetMessage:%d\n",GetLastError());break;} else {switch(msg.message) {case TM_CONSUMER:printf("get consumer message.\n");break;case TM_PRODUCER:printf("get producer message.\n");break;default:break;}}}    _endthreadex(0);    return 0;}int _tmain(int argc, _TCHAR* argv[]){// register messageDWORD workerID;HANDLE hChild,hEvent;BOOL bRet;// Create an event to prevent post Message Queue hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);// Create new threadif(0 == (hChild = chBEGINTHREADEX(NULL,0,ThreadRun,hEvent,0,&workerID))) {_tprintf(TEXT("fail to create thread.\n"));return -1;}WaitForSingleObject(hEvent,INFINITE);// Send Message to this newly created threadfor(int i = 0; i < 5; i++) {if(!(bRet = PostThreadMessage(workerID,TM_CONSUMER,0,0))) {printf("PostThreadMessage TM_CONSUMER error:%d\n",GetLastError());}if(!(bRet = PostThreadMessage(workerID,TM_PRODUCER,0,0))) {    printf("PostThreadMessage TM_PRODUCER error:%d\n",GetLastError());}}PostThreadMessage(workerID,WM_QUIT,0,0);//wait it quit WaitForSingleObject(hChild,INFINITE);CloseHandle(hChild);getchar();return 0;}


0 0
原创粉丝点击