posts - 4, comments - 6, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

关于windows、线程、消息的一点体会

Posted on 2008-01-02 19:35 hongsion 阅读(2052) 评论(5)  编辑 收藏 引用 所属分类: Windows

以下内容完全把window 操作系统当作一个黑盒,因此所有内容只能作为对其内部的一个猜测。

1. windows操作系统内部在创建一个线程的时候,会自动为它创建一个消息队列。

2.每当一个线程创建一个窗口的时候,操作系统内部都会把该窗口的Handle和线程相关联。很有可能在操作系统内部会维护一个窗口handle到线程的map. 还有一种可能就是窗口的成员变量里面有一个指针,指向创建它的线程。

3.窗口本身并没有消息队列,所有发到窗口的消息,都会自动被发到创建该窗口的线程的消息队列中。

4.每个线程只能处理自己线程队列里面的消息,不能处理其他线程消息队列里面的消息。
所以PeekMessage(LPMSG lpMsg, HWND hWnd, UINT,UINT,UINT)函数中,如果hWnd不是本线程创建的窗口,则该函数调用失败。

5.由于在线程消息队列里面的消息会包含有窗口句柄,所以PeekMessage可以专门处理某个特殊窗口的消息。


6. 曾经有疑问线程是不是只有创建了窗口才具有消息队列,但又觉得应该不是这样,因为在windows的API里面有个函数叫PostThreadMessage,可以直接把消息投递到线程的消息队列里面,而不需要任何窗口句柄。后来在MSDN里面有这么一段描述,觉得解释的很详细:
“The system maintains a single system message queue and one thread-specific message queue for each graphical user interface (GUI) thread. To avoid the overhead of creating a message queue for non–GUI threads, all threads are created initially without a message queue. The system creates a thread-specific message queue only when the thread makes its first call to one of the User or Windows Graphics Device Interface (GDI) functions".
 这里唯一的疑问我想应该是”makes its first call to one of the User or Windows Graphics Device Interface (GDI) functions", 这句话的意思是不是等同于创建一个窗口呢?

Feedback

# re: 关于windows、线程、消息的一点体会  回复  更多评论   

2009-04-03 22:22 by rico
有见地!

The system creates a thread-specific message queue only when the thread makes its first call to one of the User or Windows Graphics Device Interface (GDI) functions".

非常有意思的地方,也就是说,程序不能显示的为自己的一个线程创建消息队列。更有意思的是一篇文章说,如果你给一个线程postthreadmessage如果失败,那么对不起,等等再试,直到成功,非常滑稽的设计。最想不通的是,其他操作系统上,你爱怎么创建消息队列,你就创建,也没有什么限制,为啥微软的消息队列就必须要受限?

恐怕是早期,微软假设,一个进程一个消息队列足以。后来支持多线程了,又缺省的认为,工作线程,你别关心UI的事情,不给你消息队列。等到最后来,觉得线程消息也不错啊,这样又允许非主线程拥有消息队列,并可以在上面完成UI。总之,感觉在微软看来,消息队列除了干UI的事情,没啥用。你要在进程之间发个自定义消息,那也不是他很期望的事情。

纯属推测。

# re: 关于windows、线程、消息的一点体会  回复  更多评论   

2009-04-03 22:40 by rico
另外,PostThreadMessage,都不可以带窗口Handle的喔。当然,如果是发给窗体的,微软认为,postmessage就可以了。这就让人纳闷了,我消息不是直接发给窗体的,而是直接发给一个线程的,虽然那个窗体属于某个线程,并最终会被dispatch到对应的窗口,因为操作系统自己也登记了窗口属于那个线程(博主的推测)。

所以微软想开发者,老老实实的,你要发消息到另外一个窗口,不用告诉我窗口所在的线程,告诉我窗口句柄就可以了,我(os)晓得该怎么转发,不用你脱了裤子放屁(对我os来说)。

但是,如果程序自己保存得有窗口所在线程的Handle,你postthreadmessage就不消到操作系统查map,岂不是快些?不过感觉这是微软的惯例了,尽量封装多一点,封装死一点,这样系统看起来更复杂和高深。同时这样安装盘可以做的更大些,这样,可以可以消耗更多塑料,拉动GDP,而且是围绕微软的GDP。

# re: 关于windows、线程、消息的一点体会  回复  更多评论   

2009-05-22 11:47 by 飞鸽传书
有点难理解。

# re: 关于windows、线程、消息的一点体会  回复  更多评论   

2009-05-22 11:53 by 飞鸽传书
哈哈,表达得太好了。@rico

# re: 关于windows、线程、消息的一点体会[未登录]  回复  更多评论   

2012-01-16 17:39 by 葡萄
1. windows操作系统内部在创建一个线程的时候,会自动为它创建一个消息队列。

这个说的不对。在线程创建的时候,所有线程都是没有消息队列的。
只有这个线程中显式的调用GUI相关函数(例如创建窗口)时或者PostThreadMessage时,才会给这个线程创建消息队列。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理