[经验总结]SendMessage会等待消息处理结束吗

1
发信人: wxstorm (企鹅), 信区: VisualC
标 题: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:32:25 2011), 站内

MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。
那这个消息处理函数是在哪个线程里执行的?
调用SendMessage的线程还是窗体所在的那个线程?
--
2
发信人: cavalho (差一个r。。。), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:40:36 2011), 站内


当然是窗体所在线程

【 在 wxstorm (企鹅) 的大作中提到: 】
: MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。
: 那这个消息处理函数是在哪个线程里执行的?
: 调用SendMessage的线程还是窗体所在的那个线程?
: ...................
3
发信人: zjudm (钱塘观潮), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:42:15 2011), 站内

没有特别的事物,用post好了
【 在 wxstorm (企鹅) 的大作中提到: 】
: MSDN上说:SendMessage给另一个线程的某个窗体发送消息后,是直接发给了其消息处理函数,会等那个消息被处理后才返回。
: 那这个消息处理函数是在哪个线程里执行的?
: 调用SendMessage的线程还是窗体所在的那个线程?
: ...................

--
4
发信人: solosure (罗嗦Sure), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:42:57 2011), 站内

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的线程还是窗体所在的那个线程?

--
5
发信人: wxstorm (企鹅), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:44:30 2011), 站内

窗体所在线程的话, 那这个线程是怎么突然被打断来执行这个消息处理函数的呢? 直接把当前的执行点中断了,跳到消息处理函数那里去?
而且SendMessage的那个线程通过什么方式知道那个线程的那个函数执行完了呢?
【 在 cavalho (差一个r。。。) 的大作中提到: 】
: 当然是窗体所在线程


--
6
发信人: zjudm (钱塘观潮), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:46:39 2011), 站内

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


【 在 wxstorm (企鹅) 的大作中提到: 】
: 窗体所在线程的话, 那这个线程是怎么突然被打断来执行这个消息处理函数的呢? 直接把当前的执行点中断了,跳到消息处理函数那里去?
: 而且SendMessage的那个线程通过什么方式知道那个线程的那个函数执行完了呢?


--
7
发信人: wxstorm (企鹅), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:47:26 2011), 站内

嗯,我也看到过这段话。
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里的


--

8
发信人: solosure (罗嗦Sure), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:51:07 2011), 站内

可能是靠消息队列来实现的吧
【 在 wxstorm (企鹅) 的大作中提到: 】
: 嗯,我也看到过这段话。
: the system switches to that thread。。。这个是咋实现的?
: 这不相当于在那个线程执行过程中,突然插进来一段么?
: ...................

--
The truth is out there.
9
发信人: wxstorm (企鹅), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 21:55:25 2011), 站内

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

SendMessage应该直接越过系统消息队列和线程消息队列的吧。。。
难道除了这两个还有第三种消息队列?
【 在 solosure (罗嗦Sure) 的大作中提到: 】
: 可能是靠消息队列来实现的吧


--
10
发信人: CKevin ( ), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 23:18:12 2011), 站内

我的理解,不一定对哈。
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应该直接越过系统消息队列和线程消息队列的吧。。。
: ...................

--
如果谁还有异议,看看zhengself委员的肺腑之言,也会像我一样被感动的。
【 在 zhengself (OR:Google Lab Group) 的大作中提到: 】
: 实际上,至少是D。
: 我说她 确实至少是D 这个不是搞出来的 是自然的
: 不用YY是B还是A了,水姑娘不用挤的。
: 那是你看她照片看的少。。。。
11
发信人: cavalho (差一个r。。。), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Mon Jan 24 23:53:32 2011), 站内



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

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


--

12
发信人: firecloud (正在重启...), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 09:35:44 2011), 站内

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

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


--
13
发信人: xiaoju (可爱的龙猫), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 10:19:23 2011), 站内

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

【 在 firecloud (正在重启...) 的大作中提到: 】
: send保证对方一定立刻处理吧


--
14
发信人: firecloud (正在重启...), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 10:22:55 2011), 站内

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

【 在 xiaoju (可爱的龙猫) 的大作中提到: 】
: 不一定。万一对方的消息循环block掉了就不行。


--
15
发信人: solosure (罗嗦Sure), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 12:56:07 2011), 站内

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应该直接越过系统消息队列和线程消息队列的吧。。。
: ...................

--
The truth is out there.
16
发信人: wxstorm (企鹅), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 16:23:30 2011), 站内

嗯嗯,确实是这样,多谢!
在看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


--

17
发信人: wxstorm (企鹅), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Tue Jan 25 16:24:35 2011), 站内

嗯。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里的。


--

18
发信人: fiu (( ⊙ o ⊙ )), 信区: VisualC
标 题: Re: SendMessage问题
发信站: 水木社区 (Wed Jan 26 10:29:19 2011), 站内

我的理解:)也不一定正确
1、SendMessage以及PostMessage何时执行,怎么执行应该是从多线程的角度去考虑。
其中SendM是同步的,发送了需要等待相应线程A执行有返回才继续。PostM直接发送到
对方线程B的消息队列就返回,是异步的。

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

2、我看英文也模模糊糊的,wxstorm贴的英文我觉得也在理。SendM直接发送消息,调用
消息的wndproc应该就是Nonqueued message,而PostM这种是塞到队列去了,
其实就消息而言,我怎么感觉nonqueued message和 queued message并没有太大的时间差,
所在线程执行到了,俩都很快完成了。没执行到SendM也得组塞着。

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


【 在 CKevin ( ) 的大作中提到: 】
我的理解,不一定对哈。
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应该直接越过系统消息队列和线程消息队列的吧。。。
: ...................
为了彻底弄清这个问题,我又看了WINE的实现代码,如下: static LRESULT send_inter_thread_message( const struct send_message_info *info, LRESULT *res_ptr ) { size_t reply_size = 0; TRACE( "hwnd %p msg %x (%s) wp %lx lp %lx/n", info->hwnd, info->msg, SPY_GetMsgName(info->msg, info->hwnd), info->wparam, info->lparam ); USER_CheckNotLock(); if (!put_message_in_queue( info, &reply_size )) return 0; /* there's no reply to wait for on notify/callback messages */ if (info->type == MSG_NOTIFY || info->type == MSG_CALLBACK) return 1; wait_message_reply( info->flags ); return retrieve_reply( info, reply_size, res_ptr ); }


--

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#SendMessage和PostMessage的参数传递 在C#中可以使用Window API提供的SendMessage和PostMessage来传递参数。两者的区别简单介绍下:返回值的不同,我们先看一下 MSDN 里的声明: LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); BOOL PostMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ); 其中 4 个参数的意义是一样的,返回值类型不同(其实从数据上看他们一样是一个 32 位的数,只是意义不一样),LRESULT 表示的是消息处理后的返回值,BOOL 表示的是消息是不是 Post 成功。 2、PostMessage 是异步的,SendMessage 是同步的。 PostMessage 只把消息放入队列,不管消息是否被处理就返回,消息可能不被处理;而 SendMessage 等待消息处理完了之后才返回,如果消息不被处理,发送消息的线程将一直被阻塞。 3、如果在同一个线程内,SendMessage 发送消息时,由 USER32.DLL 模块调用目标窗口的消息处理程序,并将结果返回。SendMessage 在同一线程中发送消息并不入线程消息队列。PostMessage 发送消息时,消息要先放入线程的消息队列,然后通过消息循环分派到目标窗口(DispatchMessage)。 如果在不同线程内,SendMessage 发送消息到目标窗口所属线程的消息队列,然后发送消息的线程在 USER32.DLL 模块内监视和等待消息处理,直到目标窗口处理完返回。SendMessage 在返回前还做了很多工作,比如,响应别的线程向它 SendMessage。Post 到别的线程时,最好用 PostThreadMessage 代替 PostMessage,PostMessage 的 hWnd 参数可以是 NULL,等效于 PostThreadMessage + GetCurrentThreadId。Post WM_QUIT 时,应使用 PostQuitMessage 代替。 4、系统只整编(marshal)系统消息(0 到 WM_USER 之间的消息),发送用户消息(WM_USER 以上)到别的进程时,需要自己做整编。 用 PostMessage、SendNotifyMessage、SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息处理就返回,接受者还没处理指针就已经被释放了。 5、在 Windows 2000/XP 里,每个消息队列最多只能存放 10,000 个 Post 的消息,超过的还没被处理的将不处理,直接丢掉。这个值可以改得更大:[HKEY_LOCAL_MACHINE/SOFTWARE/ Microsoft/Windows NT/CurrentVersion/Windows] USERPostMessageLimit,最小可以是 4000。 PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMessage必须等到消息处理后才返回。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值