《Win32多线程程序设计》学习笔记 第11章 GDI 与窗口管理

Win32中,每个线程都有自己专属的消息队列,并不是每个窗口都有自己的消息队列。因为每个线程能够产生很多窗口,如果一个线程停止响应,或者它忙于一段耗时的计算工作,那么由它差生的窗口统统都会停止响应,但系统中的其他窗口还是继续正常的运作。

所有传递给某一窗口的消息,将由产生该窗口之线程负责处理。

对窗口所做的任何一个事情基本上都由该窗口的窗口函数处理,并因此被产生该窗口的线程处理。

SendMessage()

同一线程:直接调用窗口函数

不同线程:切换到新线程并调用窗口函数 ,在该函数返回之前,SendMessage不会返回(所以会发生意Context Switch,比一般函数调用费时间)

PostMessage()

同一线程:把消息放入消息队列立即返回

不同线程:立即返回,消息放入另一线程的消息队列中

 ----------------------------------------------------

所以如果各个窗口都有自己的线程,那么在处理各个窗口的响应时可能要发生很多次的context switch ,效率低下,所以不能有自己的线程。

如果一个线程调用了SendMessage后,当前线程就会等待其返回,类似于sleep状态,但是还是可以处理 外界对其窗口的sendMessage操作。

如果某个线程正在 处理由其他线程Send过来的消息,可以在该线程中调用IsSendMessage,会获得TRUE。为了让调用端线程能够继续工作,我们可以调用ReplyMessage。

为了防止线程因为SendMessage导致的死锁(永远醒不过来) ,Win32提供2个函数。第一个是SendMessageTimeout,允许你指定一个时间,时间终了了一定会返回。第二个是SendMessageCallback。这个函数会立刻返回。

 ------------------------------------------------

欲在一个MDI程序中有效率的使用多个线程,建议是以一个线程处理所有的用户输入以及用户界面的管理。用其他线程做一些后台的耗时操作。不管怎么做,主线程应该始终有回应。

线程之间的通讯

线程通常需要传递数据给另外一个线程,worker线程告诉别人他的工作做完了,GUI线程可以需要交给worker线程一个新工作。PostThreadMessage 类似于PostMessage,不过他的参数之一不是窗口的handle,而是线程ID,当然,接收端必须有消息队列。

BOOL PostThreadMessage(          
    DWORD idThread,  
// 线程ID,可以有GetCurrentThreadID或CreateThread获得
    UINT Msg,      
    WPARAM wParam,
    LPARAM lParam
);

返回值:如果成功的Post出去,返回TRUE。

以消息作为通讯方式,比起标准技术如全局变量等,有很大好处,比如目标线程很忙碌,则负责post的那个线程不会停滞下来。如果对象是同一进程的线程,可以自定义消息,如WM_APP+0X100等,并配置一块结构,防止你想要传递的数据。然后把结构指针当做lParam,接收端在处理完消息后负责释放内存。

锁住GDI对象

 GDI对象被每个进程拥有,而被每个线程锁定。如果一个线程正在使用一个GDI对象,该对象将被锁定,其他线程没有办法在使用它。

 

 

 

 

 

 

转载于:https://www.cnblogs.com/kwliu/archive/2010/12/25/2195905.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值