关于消息循环
来源:互联网 发布:淘宝店铺收藏 编辑:程序博客网 时间:2024/06/05 20:08
最近尝试在多线程里使用消息队列代替事件和临界区
原因很简单,内核对象太多维护复杂,虽然处理消息队列的逻辑也很复杂,但相对维护一堆内核对象句柄要容易得多
而且,不影响执行效率(消息队列自动销毁,创建只要调用一次相关的API即可,比如user32.dll的函数)
然而奇怪的事情出现了,在几个线程空闲时CPU占用率很高
代码诸如此类:
while(True){// 获取线程消息和窗口消息dwRet = PeekMessageA(&stMsg, NULL, 0, 0, PM_REMOVE);// PM_NOYIELDif(dwRet == FALSE){Sleep(0);continue;// 没有消息, 放弃当前线程时间片, 继续循环}if(stMsg.message == WM_QUIT){break;// 退出消息}...
True是我自定义的布尔枚举,值为1
Sleep(0);是主动放弃当前线程时间片,这个在之前XP下屡试不爽,经常以此代替GetMessage()
因为GetMessage的文档太罗嗦,比如WM_QUIT返回值不同,错误返回-1
我试着创建两个空闲线程,结果CPU占了50%,正好使用了两个核心(我的cpu是FX-4100推土机,4核3.6GHz)
也就是说,狗R的根本没放弃线程时间片?
于是跟踪进去,发现Sleep(0)断点瞬间继续,说明放弃了又被调度了!!
查MSDN
ParametersdwMilliseconds [in] The time interval for which execution is to be suspended, in milliseconds. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution. Windows XP: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. This behavior changed starting with Windows Server 2003. A value of INFINITE indicates that the suspension should not time out.
也就是说xp下是相同优先级的线程,而之后就是所有的线程,只要没有等待运行的线程就会立刻继续当前线程
之前在单核和双核的时代,线程几乎是超过核心数的运行
现在四核下由于空闲核心多,导致线程一直被调度,最后表现出来是没有放弃时间片
同样的,SleepEx和SwitchToThread也是一样的道理
难道用GetMessage?当然可以
不过也可以多加一行代码
while(True){// 获取线程消息和窗口消息dwRet = WaitMessage();dwRet = PeekMessageA(&stMsg, NULL, 0, 0, PM_REMOVE);// PM_NOYIELDif(dwRet == FALSE){Sleep(0);continue;// 没有消息, 放弃当前线程时间片, 继续循环}if(stMsg.message == WM_QUIT){break;// 退出消息}...
整个世界,安静了.
不过这一爆的余波不小,我一下子想到POCT项目催生的游侠基础类库,急忙翻看窗口类的消息循环
发现当时赶时间,偷懒用了GetMessage(),反正完成相同的工作效果,偷懒就是一种艺术
那么是不是PeekMessage就是为了文档简单呢
不是,如果放到游戏开发,需要尽可能使用CPU资源的时候,你是打死都不想要GetMessage的
这时候只要把WaitMessage删掉,注释掉即可,当然循环流程最好重构,比如改为1秒Peek一次,以提升主要事务时间占用率
腾讯从韩国买来的次品穿越火线开始的时候为什么切换桌面会卡个大半年(其实我估计现在CF的陈年老伤一直都在)
因为他们在游戏循环里都没有处理Windows消息,导致线程没有响应(键盘鼠标是DirectX驱动处理的,游戏里不影响)
微软老一辈工程师辛辛苦苦设计的架构,本来是很强大的东西,
大多数都被浪费了,就好像Office VBA
- 关于消息循环
- 关于windows程序的消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 消息循环
- 关于Windows中的系统消息循环占用CPU的疑问
- 消息队列与消息循环
- windows消息与消息循环
- 消息和消息处理之消息循环
- MFC中的消息循环
- CSDN-markdown编辑器语法——字体、字号与颜色
- Selenium控制流程(显示等待与隐式等待)
- 递归层次汇总查询
- flume配置-生产环境下从文件目录下将日志上传到s3
- 复选框练习
- 关于消息循环
- 鼠标右键事件
- 44-中断系统调用与自动重启动
- tcp中RACK算法
- 特征缩放(Feature Scaling)
- 【Android】条形码/二维码扫描——ZXing源码分析及相关jar包导入
- Android 实现微信支付那些事
- ngin 安装成设置 pathinfo
- 如何清除缓冲区中的字符,防止scanf函数的误读?