SendMessage问题

wxstorm
企鹅 2011-01-24 字数 196

MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。

那这个消息处理函数是在哪个线程里执行的?

调用SendMessage的线程还是窗体所在的那个线程?

VisualC VC程序设计
17 个回复
cavalho
差一个r。。。 2011-01-24

当然是窗体所在线程

【 在 wxstorm (企鹅) 的大作中提到: 】

: MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。

: 那这个消息处理函数是在哪个线程里执行的?

: 调用SendMessage的线程还是窗体所在的那个线程?

: ...................

wxstorm
企鹅 2011-01-24

窗体所在线程的话, 那这个线程是怎么突然被打断来执行这个消息处理函数的呢? 直接把当前的执行点中断了,跳到消息处理函数那里去?

而且SendMessage的那个线程通过什么方式知道那个线程的那个函数执行完了呢?

【 在 cavalho (差一个r。。。) 的大作中提到: 】

:   当然是窗体所在线程

zjudm
钱塘观潮 2011-01-24

没有特别的事物,用post好了

【 在 wxstorm (企鹅) 的大作中提到: 】

: MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。

: 那这个消息处理函数是在哪个线程里执行的?

: 调用SendMessage的线程还是窗体所在的那个线程?

: ...................

solosure
solo兽 2011-01-24

If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure.

这句话也是MSDN里的

【 在 wxstorm (企鹅) 的大作中提到: 】

: MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。

: 那这个消息处理函数是在哪个线程里执行的?

: 调用SendMessage的线程还是窗体所在的那个线程?

wxstorm
企鹅 2011-01-24

嗯,我也看到过这段话。

the system switches to that thread。。。这个是咋实现的?

这不相当于在那个线程执行过程中,突然插进来一段么?

所以不太理解是咋回事。。。

【 在 solosure (罗嗦Sure) 的大作中提到: 】

: If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window proc

: 这句话也是MSDN里的

zjudm
钱塘观潮 2011-01-24

消息是红豆,由队列抛洒,谁接了就是谁的

【 在 wxstorm (企鹅) 的大作中提到: 】

: 窗体所在线程的话, 那这个线程是怎么突然被打断来执行这个消息处理函数的呢? 直接把当前的执行点中断了,跳到消息处理函数那里去?

: 而且SendMessage的那个线程通过什么方式知道那个线程的那个函数执行完了呢?

solosure
solo兽 2011-01-24

可能是靠消息队列来实现的吧

【 在 wxstorm (企鹅) 的大作中提到: 】

: 嗯,我也看到过这段话。

: the system switches to that thread。。。这个是咋实现的?

: 这不相当于在那个线程执行过程中,突然插进来一段么?

: ...................

wxstorm
企鹅 2011-01-24

不会吧。

Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue

SendMessage应该直接越过系统消息队列和线程消息队列的吧。。。

难道除了这两个还有第三种消息队列?

【 在 solosure (罗嗦Sure) 的大作中提到: 】

: 可能是靠消息队列来实现的吧

CKevin
2011-01-24

我的理解,不一定对哈。

Send并不会越过消息队列。如果他直接调用消息处理过程,那如何说是切换到另一个线程;如果他立即要求对方中断手头的工作,那对方如果正在做重要的事情或者在内核态怎么办。我觉得应该是Send把消息交给对方的队列,然后等待对方的消息获取过程比如Get得到并处理消息,Send再返回吧。之所以说Send会调用消息处理过程,那是因为只有消息处理过程才会处理这个消息;另一方面,Send也没保证自己一直阻塞着,也没保证对方必须立即处理不是。

【 在 wxstorm (企鹅) 的大作中提到: 】

: 不会吧。

: Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue

: SendMessage应该直接越过系统消息队列和线程消息队列的吧。。。

: ...................

cavalho
差一个r。。。 2011-01-24

差不多是这样,大家可以去看看REACTOS的源码

【 在 CKevin (  ) 的大作中提到: 】

: 我的理解,不一定对哈。

: Send并不会越过消息队列。如果他直接调用消息处理过程,那如何说是切换到另一个线程;如果他立即要求对方中断手头的工作,那对方如果正在做重要的事情或者在内核态怎么办。我觉得应该是Send把消息交给对方的队列,然后等待对方的消息获取过程比如Get得到并处理消息,Sen

firecloud
正在重启... 2011-01-25

send保证对方一定立刻处理吧

【 在 CKevin (  ) 的大作中提到: 】

: 我的理解,不一定对哈。

: Send并不会越过消息队列。如果他直接调用消息处理过程,那如何说是切换到另一个线程;如果他立即要求对方中断手头的工作,那对方如果正在做重要的事情或者在内核态怎么办。我觉得应该是Send把消息交给对方的队列,然后等待对方的消息获取过程比如Get得到并处理消息,Sen

xiaoju
可爱的龙猫 2011-01-25

不一定。万一对方的消息循环block掉了就不行。

【 在 firecloud (正在重启...) 的大作中提到: 】

: send保证对方一定立刻处理吧

firecloud
正在重启... 2011-01-25

这种情况sendmessage本身也会阻塞住

【 在 xiaoju (可爱的龙猫) 的大作中提到: 】

: 不一定。万一对方的消息循环block掉了就不行。

solosure
solo兽 2011-01-25

Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

这是接着那句话的,也是MSDN里的。

【 在 wxstorm (企鹅) 的大作中提到: 】

: 不会吧。

: Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue

: SendMessage应该直接越过系统消息队列和线程消息队列的吧。。。

: ...................

wxstorm
企鹅 2011-01-25

嗯嗯,确实是这样,多谢!

在看GetMessage和PeekMessage时看到了。MSDN里的:

During this call, the system delivers pending messages that were sent to windows owned by the calling thread using the SendMessage, SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. The system may also process internal events. Messages are processed in the following order:

Sent messages

Posted messages

Input (hardware) messages and system internal events

Sent messages (again)

WM_PAINT messages

WM_TIMER messages

嗯,我的理解是GetMessage和PeekMessage把该干的事都干了,如果是sent messages,GetMessage相当于直接dispatchMessage了,而且是把所有的sent messages都处理完了,才检查队列消息。

所以如果sent messages没有窗口,相当于啥事也干不了,不起作用,即线程消息只能post,故存在PostMessage和PostThreadMessage两个函数,但只有SendMessage,没有对应的SendThreadMessage..

【 在 CKevin (  ) 的大作中提到: 】

: 我的理解,不一定对哈。

: Send并不会越过消息队列。如果他直接调用消息处理过程,那如何说是切换到另一个线程;如果他立即要求对方中断手头的工作,那对方如果正在做重要的事情或者在内核态怎么办。我觉得应该是Send把消息交给对方的队列,然后等待对方的消息获取过程比如Get得到并处理消息,Sen

wxstorm
企鹅 2011-01-25

嗯。message retrieval code应该就是GetMessage/PeekMessage之类的吧。

多谢楼上的各位大大们哈。

【 在 solosure (罗嗦Sure) 的大作中提到: 】

: Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

: 这是接着那句话的,也是MSDN里的。

Fiu
胸有丘壑乌道本 2011-01-26

我的理解:)也不一定正确

1、SendMessage以及PostMessage何时执行,怎么执行应该是从多线程的角度去考虑。

其中SendM是同步的,发送了需要等待相应线程A执行有返回才继续。PostM直接发送到

对方线程B的消息队列就返回,是异步的。

同步和异步什么时候执行,我感觉应该也看时间片什么时候轮循到相应的线程

2、我看英文也模模糊糊的,wxstorm贴的英文我觉得也在理。SendM直接发送消息,调用

消息的wndproc应该就是Nonqueued message,而PostM这种是塞到队列去了,

其实就消息而言,我怎么感觉nonqueued message和 queued message并没有太大的时间差,

所在线程执行到了,俩都很快完成了。没执行到SendM也得组塞着。

这俩的区别更大的是同步和异步上的区别。CK大牛的Send没保证自己阻塞是不是需要核实一下 :)

我的理解,不一定对哈。

Send并不会越过消息队列。如果他直接调用消息处理过程,那如何说是切换到另一个线程;如果他立即要求对方中断手头的工作,那对方如果正在做重要的事情或者在内核态怎么办。我觉得应该是Send把消息交给对方的队列,然后等待对方的消息获取过程比如Get得到并处理消息,Send再返回吧。之所以说Send会调用消息处理过程,那是因为只有消息处理过程才会处理这个消息;另一方面,Send也没保证自己一直阻塞着,也没保证对方必须立即处理不是。

【 在 wxstorm (企鹅) 的大作中提到: 】

如果谁还有异议,看看zhengself委员的肺腑之言,也会像我一样被感动的。

【 在 zhengself (OR:Google Lab Group) 的大作中提到: 】             

:         实际上,至少是D。                                        

:         我说她 确实至少是D 这个不是搞出来的 是自然的             

:         不用YY是B还是A了,水姑娘不用挤的。                       

:         那是你看她照片看的少。。。。                             

【 在 CKevin (  ) 的大作中提到: 】

: 不会吧。

: Nonqueued messages are sent immediately to the destination window procedure, bypassing the system message queue and thread message queue

: SendMessage应该直接越过系统消息队列和线程消息队列的吧。。。

: ...................