带有消息队列的线程的两种应用
时间:2011-03-26 来源:GhostEx
我本人常用的两种带消息队列的线程的应用方法:阻塞应用与非阻塞应用
阻塞版本的特点:有命令,就工作;没命令来,就休息。不占用额外CPU时间。
非阻塞版本的特点:有命令,就工作;没命令来,就干点默认该干的事情,比如维护对象的刷新等等。一般要在这里加个延时,否则会不停的PeekMessage,而导致100%的CPU占用。
向线程发消息,使用PostThreadMessage函数。
以下是代码例子:
//阻塞版本
UINT WINAPI Thread_VC( LPVOID arg )
{
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); //强制产生线程的消息队列
while (1)
{
try
{
if(GetMessage(&msg,NULL,0,0))//如果没有消息,会一直阻塞在这里
{
if (msg.message==WM_CLOSE)
{
break;
}
switch(msg.message)//在这个Switch中,根据收到的不同的消息代码,实现不同的功能
{
case 0:
break;
}
}
}
catch(...)
{
;
}
}
return 0;
}
//以下是本线程的非阻塞版本
UINT WINAPI Thread_VC(LPVOID arg)
{
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); //强制产生线程的消息队列
while (1)
{
//检查消息队列中是否有消息。
if( PeekMessage(&msg,0,0,0,PM_NOREMOVE) )
{
//确认有新的消息。现在处理它
if (msg.message==WM_CLOSE||msg.message==WM_QUIT)
{
break;//结束线程
}
if(GetMessage(&msg,NULL,0,0))
{
switch(msg.message)//在这个Switch中,根据收到的不同的消息代码,实现不同的功能
{
case WM_SUSPEND_THREAD://我额外加的,支持线程暂停和恢复。与API的暂停线程还是有区别的
{
BOOL bQuit=FALSE;
TRACE(TEXT("Suspend Thread !\n"));
while(GetMessage(&msg,NULL,WM_RESUME_THREAD,WM_RESUME_THREAD)
||GetMessage(&msg,NULL,WM_CLOSE,WM_CLOSE)
||GetMessage(&msg,NULL,WM_QUIT,WM_QUIT))
{
TRACE(TEXT("Resume Thread !\n"));
if (msg.message==WM_CLOSE||msg.message==WM_QUIT)
bQuit=TRUE;
break;
}
if(bQuit)
{
goto END_POINT;
}
}
break;
default:
break;
}
}
}
DoSomeThing();//不处在阻塞区域,此处的代码会无限执行
}
END_POINT:
//在这里做一些清理工作
return 0;
}
相关阅读 更多 +