吵吵   2011-07-03  阅读:4,595

我想多线程的强大大家都已经了解的非常清楚,可以说因为有了多线程,我们在windows下的多任务才能真正意义上的实现。才能开着QQ、打着游戏却不会耽误事儿。对于一个程序开发者来说,线程的使用已经非常的普遍,不管什么程序,总要来个多线程,从2到n个线程不等。尤其是涉及到了网络通讯的时候,不用线程那就要等很久才能收到数据,难道这段时间就让程序死着?

用到多线程自然是要用到线程间的通信,可以是多个线程间的通信,也可以是线程与主线程,或者说是我们的主程序进行通信。实现通信的方法大概来说有两种比较常用。一是定义全局变量,这个比较方便,在线程中直接改我们的全局变量就行了,但是涉及到多线程的同步,即要对我们的数据的读写进行保护,这个又比较麻烦了。
然后用的就是利用消息传递了。在vc中我们会常用到线程类,而这个线程类已经提供了一个我们发送线程消息的函数了,用法很简单,只要有线程类的句柄我们就可以用该方法发消息:
pThread->PostThreadMessage(WM_MyMessage,0,0);
WM_MyMessage是我们自己定义的消息,可以在头部定义大于1000的一个消息:
#define WM_MyMessage (WM_USER + 100)
若是不是用的mfc的线程类的话,我们可以看看postthreadmessage这个api:
函数功能:该函数将一个消息放入(寄送)到指定线程的消息队列里,不等待线程处理消息就返回。   
函数原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam,LPARAM IParam);   
参数   
idThread:其消息将被寄送的线程的线程标识符。如果线程没有消息队列,此函数将失败。当线程第一次调用一个Win 32 USER或GDI函数时,系统创建线程的消息队列。要得到更多的信息,参见备注。   
Msg:指定将被寄送的消息的类型。   
wParam:指定附加的消息特定信息。   
IParam:指定附加的消息特定信息。   
返回值:如果函数调用成功,返回非零值。如果函数调用失败,返回值是零。若想获得更多的错误信息,请调用GetLastError函数。如果idThread不是一个有效的线程标识符或由idThread确定的线程没有消息队。
我们获取到了线程的标示也可以轻易的发送消息。
发送消息不难,但是我们线程如何接受消息然后执行结束线程或者其它动作呢,我们知道强行中断线程线程中的内存并不能立即释放,所以我们希望是通过接收到消息,然后线程正常结束,这样子变量也就释放了。要完成线程消息的接收主要是有一个循环:

while (isLoop)
{

while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_MyMessage)
{
if(msg.wParam==0)
{
return 0; //线程正常返回,会释放局部变量等内存资源
}
else if(msg.wParam==1)
{
// strcpy(ipAdrress,userInfo.ip);

}

}
else
{
DispatchMessage(&msg);
}
}
}

可以看到在线程中我们需要有一个主循环,单又消息来了的时候要把消息给拾取出来,然后进行相关的操作,如return 0就是将线程函数给返回了,线程也就结束了,线程的内存也就完全释放了,所以要用到线程消息不难,难的是如何根据你的功能,能够巧妙的实现这样一个线程内的循环,以使线程能够对消息进行响应,这个也是你水平的高低了。

吵吵微信朋友圈,请付款实名加入:

吵吵 吵吵

16条回应:“vc中多线程消息通信”

  1. 大成说道:

    来看看,不是很了解。哈哈。

  2. 阿木说道:

    希望能和博主长期交流!

  3. 流氓兔说道:

    来支持博主了

  4. 张海华说道:

    哥不搞VC!!

  5. 天玉有双说道:

    博主对机顶盒解码也应该很懂啊!

    • 吵吵说道:

      这个东西没研究过,我研究过openwrt路由,用到的ttl刷机线老板说可以刷机顶盒,有时间看看。

  6. 邮票说道:

    学好VC很重要,很多软件都是这个开发的。

  7. Royal说道:

    现在得用线程池咯..

    • 吵吵说道:

      线程池是.net框架下的,c#多用它,不过我不知道现在vc是否也可以用了。

  8. Royal说道:

    线程池是一种设计模式,和语言木有关系啊,看具体需求了

    • 吵吵说道:

      哦哦 是这样子啊 恩 有时间要去看看 我一直以为线程池是c#中才用呢

发表评论

电子邮件地址不会被公开。 必填项已用*标注