因为平时基于windows的编程开发了几个项目,特别在MFC环境下,不可避免的基于消息的处理,作为一个PC客户端开发人员,对于消息的调度必须要熟练。而且,面试中这也是一个老生常谈的问题,如果你面试windows开发的话,不能比较完整阐述消息调度的思想,那么我觉得你是不合格的。
windows的事件驱动核心是消息。很多人第一反应是消息队列,windows按照消息队列先进先出的来处理消息 ,我觉得这是不严谨详细的,因为如果是按照先进先出,就没有体现调度。windows的消息调度是在消息队列的前提下按照优先级处理,最高优先级是别的线程发过来的消息,这里又得提一道经典面试题目sendmssage和postmessage的区别,我相信有开发功底的都知道 ,最高优先级是sendmessage发过来的消息,其次是处理登记队列消息,后面是处理QS_QUIT标志,处理虚拟输入队列,处理WM_PAINT,最后是WM_TIMER.
我面试过字节跳动,那会儿面试官会在消息队列上深入三问四问,如果你答题不严谨,他立马知道你答题水平,会虚晃一枪,让你回答一个窗口的建立需要那几个步骤,或者说哪几个消息,而这个时候如果是老手一定会特别强调消息的调度,罗列出窗口建立经历的消息,然后特别强调WM_PAINT的刷新。
而在这个消息调度的延申是谷歌Chromium基于异步通信的多线程模型。这个模型堪称经典,我相信无论是前端还是后端,在各个大厂中都是鉴于这个模型去设计自己的框架。谷歌异步通信是两个线程A,B;线程A去请求线程B执行任务,只需将任务封装成一个闭包投递到对方线程的任务队列即可,无需等待,减少卡顿。如果线程B有空闲时间执行自然执行完毕后会通知线程A,这样就形成了一个闭合回路。当然如果有线程ABC,那么可以通过线程A投递给线程B,线程B投递给线程C,然后线程C返回给线程B,线程B返回给线程A。
这个异步通信相比于常见的基于锁的线程运行模式,减少了锁的开销,提高了线程的响应性。由于windows的消息队列,在MFC中经常消息满天飞,然后出现消息重复消息过滤不全的局面。
这种基于异步通信的多线程模型,要求设计好各个子模块及其对应的数据结构,使得在协作时可以最大程度地进行异步通信。QT的信号与槽也是基于这种设计思想建立的。我做过也给游戏模拟器的项目,客户端使用duilib+Chromium异步回路,极大的避免了很多不必要的麻烦。
如果能在回答windows的消息调度的同时,把谷歌的异步通信多线程模型阐述一下,那么我觉得你会很稳,因为这表明你熟悉windows的同时又接触到了优秀的核心框架。
标签: windows