MFC中PostMessage()多线程调用及变量安全的技术咨询
MFC多线程消息交互与线程安全问题
我目前正在开发一个MFC项目,该项目运行多个线程,使用PostMessage()实现工作线程与主UI线程间的消息交互。我编写了如下代码:
UINT ThreadFunc (LPVOID pParam) { pointerToMainUI->PostMessage(WM_EXAMPLE, MSG_EXAMPLE_1, 1); pointerToMainUI->PostMessage(WM_EXAMPLE, MSG_EXAMPLE_2, 2); // Question 1 } void MyDialogExClass::OnBnClickedStart() { int intA = 0; // Declared in header as public global mThreadA = AfxBeginThread(ThreadFunc , this); mThreadB = AfxBeginThread(ThreadFunc , this); // Question 2 } LRESULT MyDialogExClass::WinProc (WPARAM wParam, LPARAM lParam) { int iParam = (int)lParam; switch (wParam) { case MSG_EXAMPLE_1: intA = iParam; break; case MSG_EXAMPLE_2: // Do Something break; } return LRESULT(); }
我的应用需要保证FIFO机制,因此担心数据和内存存在风险,现提出两个问题:
- 线程连续调用两次
PostMessage()是否安全? - 两个不同线程修改主线程的变量是否安全?
问题1解答:线程连续调用两次PostMessage()是否安全?
- 连续调用
PostMessage()本身是线程安全的:Windows系统为每个线程维护的消息队列是线程安全结构,调用PostMessage()会把消息追加到目标线程(主UI线程)的消息队列尾部,严格遵循FIFO顺序。 - 你在同一个工作线程里先后发送的
MSG_EXAMPLE_1和MSG_EXAMPLE_2,会按调用顺序进入主UI线程的消息队列,主UI线程的消息循环也会按这个顺序处理消息,完全符合你需要的FIFO要求。 - 唯一需要注意的是:主UI线程必须保证消息循环正常运行、不被长时间阻塞,否则消息会在队列中堆积,但这属于消息处理效率问题,和
PostMessage()调用本身的安全性无关。
问题2解答:两个不同线程修改主线程的变量是否安全?
- 从你的代码逻辑来看,是安全的:两个工作线程并没有直接修改
intA,而是通过PostMessage()把修改请求发送给主UI线程,最终由主UI线程在自己的WinProc函数里完成intA的赋值操作。 - 因为只有主UI线程会操作
intA,不存在多个线程并发修改同一个变量的场景,自然不会出现数据竞争或内存风险。 - 反过来,如果工作线程直接去修改
intA(跳过PostMessage让主线程处理的步骤),那这种操作就是不安全的,必须使用同步机制(比如CCriticalSection临界区)来保护intA的访问。
内容的提问来源于stack exchange,提问作者CharonEXE
相关产品推荐
相关产品推荐

