MFC:从另一个线程调用 CWnd 方法是否安全?
MFC: Is it safe to call CWnd methods from another thread?
其实我有两个问题:
- 从工作线程调用
SendMessage
安全吗?
- 执行
CWnd
方法,例如 MessageBox
,在幕后调用 API 函数 SendMessage
?
根据我的理解,当工作线程调用SendMessage
时,它会将消息推入UI线程的消息队列中,并等待直到该消息被处理。在那种情况下,这样做是安全的。
我不太确定这个。如果我错了,请纠正我。
非常感谢。
------------------------更新-------------------- --------------
作为结论:
- 跨线程调用 windows API
::SendMessage
和 ::PostMessage
是安全的。
- 跨线程调用
CWnd
方法是不安全的。有些方法可能是安全的,但不能保证。
非常感谢大家。
Is it safe to call SendMessage
from a worker thread?
是的。系统确保消息处理在接收线程上被序列化。跨线程发送消息时,发送方被阻塞,直到消息被处理。接收方在执行消息检索代码(GetMessage
、PeekMessage
等)时仅处理 cross-thread 发送的消息。已发送的消息永远不会 queued 在消息 queue 中。 SendMessage 的文档有更多详细信息。
Do CWnd
methods, like MessageBox
, call API function SendMessage
behind the scene?
是的。首先,消息框将接收标准的 window 消息,例如 WM_CREATE
或 WM_NCCREATE
作为对话构造的一部分。此外,对于拥有的 windows(如模态对话框),系统将向正在停用的 window 和正在激活的 window 发送 WM_ACTIVATE
消息。不过,我不确定为什么这很重要,或者你为什么特别问这个问题。
现在你标题中的问题:
Is it safe to call CWnd
methods from another thread?
一般来说,不会。不过,这确实取决于成员。有些可以安全调用,有些则不能。特别是,所有修改 window 状态(内容、可见性、激活等)的方法只能从创建 window 的线程调用。如果调用不安全,系统仍将处于一致状态。但是,您的应用程序可能不是。
线程访问 UI 的 ONLY 方法是使用 SendMessage
或 PostMessage
.
考虑一台只有一个内核的机器,其中发生上下文切换并且您从工作线程直接访问 UI,您可能会破坏 UI 线程寄存器!
基本上每个 UI 框架都提供了一种机制(很多次是几种),用于从线程进行 UI 更改。例如 Android 提供 ASyncTask
和 Handler
.
其实我有两个问题:
- 从工作线程调用
SendMessage
安全吗? - 执行
CWnd
方法,例如MessageBox
,在幕后调用 API 函数SendMessage
?
根据我的理解,当工作线程调用SendMessage
时,它会将消息推入UI线程的消息队列中,并等待直到该消息被处理。在那种情况下,这样做是安全的。
我不太确定这个。如果我错了,请纠正我。
非常感谢。
------------------------更新-------------------- --------------
作为结论:
- 跨线程调用 windows API
::SendMessage
和::PostMessage
是安全的。 - 跨线程调用
CWnd
方法是不安全的。有些方法可能是安全的,但不能保证。
非常感谢大家。
Is it safe to call
SendMessage
from a worker thread?
是的。系统确保消息处理在接收线程上被序列化。跨线程发送消息时,发送方被阻塞,直到消息被处理。接收方在执行消息检索代码(GetMessage
、PeekMessage
等)时仅处理 cross-thread 发送的消息。已发送的消息永远不会 queued 在消息 queue 中。 SendMessage 的文档有更多详细信息。
Do
CWnd
methods, likeMessageBox
, call API functionSendMessage
behind the scene?
是的。首先,消息框将接收标准的 window 消息,例如 WM_CREATE
或 WM_NCCREATE
作为对话构造的一部分。此外,对于拥有的 windows(如模态对话框),系统将向正在停用的 window 和正在激活的 window 发送 WM_ACTIVATE
消息。不过,我不确定为什么这很重要,或者你为什么特别问这个问题。
现在你标题中的问题:
Is it safe to call
CWnd
methods from another thread?
一般来说,不会。不过,这确实取决于成员。有些可以安全调用,有些则不能。特别是,所有修改 window 状态(内容、可见性、激活等)的方法只能从创建 window 的线程调用。如果调用不安全,系统仍将处于一致状态。但是,您的应用程序可能不是。
线程访问 UI 的 ONLY 方法是使用 SendMessage
或 PostMessage
.
考虑一台只有一个内核的机器,其中发生上下文切换并且您从工作线程直接访问 UI,您可能会破坏 UI 线程寄存器!
基本上每个 UI 框架都提供了一种机制(很多次是几种),用于从线程进行 UI 更改。例如 Android 提供 ASyncTask
和 Handler
.