PostMessage还有两点要注意,否则容易引发低概率问题,很难排查。
第一, PostMessage调用会失败,比如消息队列限制是2000(系统注册表配置),队列如果已满是无法再次发送消息。
第二, PostMessage调用完的下一行代码与消息处理的代码,它们的执行顺序,由于多线程切换无法预期,所以谁先谁后都有可能。
先看一段不严谨的实现,A线程调用MoveWindow接口给hWnd发送自定义消息WM_MOVE_WINDOW让hWnd所在的B线程调用MoveWindow系统API移动窗口。
这段代码存在两个问题:
第一, PostMessage没有判断失败,如果失败WM_MOVE_WINDOW消息将不会被处理,pRect对象将不会释放,内存泄漏。
第二, PostMessage调用下一行代码打印日志使用pRect对象,此时WM_MOVE_WINDOW消息可能已经处理完,pRect对象已被释放成野指针。
严谨的实现