对线程间SendMessage的解疑

上面说过线程内SendMessage只是简单的调用指定窗口的窗口过程。

而线程间SendMessage时,发送线程不可能直接调用目标窗口的窗口过程,因为发送线程无法运行在接收线程的地址空间中。因此实际过程是发送线程挂起,然后由另外的线程处理消息。过程是:

首先发送的消息被追加到接收线程的发送消息队列中(send-message queue),并设置线程的QS_SENDMESSAGE标志。这个队列跟邮递消息队列(post-message queue,即之前所谓的消息队列)是并列的,之间没有关系。另外还有一个应答消息队列(reply-message queue),这在后面会用到。

之后,如果接收线程已经在执行其它代码,则暂时不会处理该消息。当接收线程进入等待消息时(如调用GetMessage、PeekMessage或WaitMessage),Windows系统首先检查线程的QS_SENDMESSAGE唤醒标志是否设置,如果设置,则系统扫描发送消息队列中消息的列表,并找到第一个发送的消息。

当接收线程等待消息时,系统从发送消息队列中取出第一个消息并调用相应的窗口过程来处理消息。如果发送消息队列中不再有消息,则QS_SENDMESSAGE被关闭。当接收线程处理消息时,调用SendMessage的线程设置成idle状态,并等待一个消息出现在它的应答消息队列中。在发送的消息处理之后,窗口过程的返回值等级到发送线程的应答消息队列中。发送线程被唤醒,取出包含映带消息队列中的返回值,即SendMessage的返回值。然后发送线程继续执行。

当线程等待SendMessage返回时,基本时处于idle状态。但当其它线程向该线程的窗口发送消息时,系统要立即处理消息,而不用象前一段说过的等待线程调用GetMessage、PeekMessage或WaitMessage时才处理线程间的Send消息。

虽然线程间的非队列(Send)消息也是发送的队列中的,但与post消息有两个主要区别:

1.队列不同,分别是send-message queue和post-messag queue。

2.获取消息途径不同。Post型消息是接收线程通过GetMessage获得的;而Send型消息则是通过系统从队列中提取,然后调用该消息的对应窗口进行执行,这个过程在接收线程等待消息时才执行。

posted @ 2013-10-21 19:51  trxdy  阅读(2103)  评论(0编辑  收藏  举报