我在一个高度多线程的应用程序上遇到了无数次崩溃。
阅读这些 MSDN page , technical note和 this article on TLS ,我已经了解 CWnd
对象被映射到 Thread Local Storgae(TLS,这是一个线程相关的内存访问)中的 HWND。
我打算解耦所有看起来像 CWnd 线程远程访问的东西,并将其转换为 HWND
引用,然后使用 ::PostMessage
作为通信端口。
但是我的一位同事真的坚持要我只在老外线程中保留CWnd*
,采用::PostMessage
策略ok,但是使用CWnd::GetSafeHwnd()
或外部线程中的pMyCWnd->m_hWnd
以恢复 native HWND
。
我一直在争论无处我已经看到GetSafeHwnd()
是线程安全的,并且CWnd
objet 在TLS 中,它在另一个线程中的值是不同的。
我错了吗? MSDN 显然使用了术语意外结果。
关于从创建者线程在外部线程中调用 CWnd::GetSafehwnd()
或 pMyCWnd->m_hWnd
,您有什么看法?
您是否有任何 MSDN 文档表明这是安全的或不安全的。
最佳答案
CWnd 没有映射到 HWND; HWNDs 映射到 CWnds,这是在每个线程的基础上发生的。 CWnd 对象不在 TLS 中(那将如何工作?)但临时 CWnd 对象是按线程创建的。
从错误的线程访问临时 CWnd 对象绝对不是一个好主意(原因由 Mark Ransom 描述)。
但是,如果您有一个永久的 CWnd 对象(例如,表示您应用程序的主窗口),那么一旦它被创建,从任何线程访问 m_hWnd 成员就完全没有问题。它只是内存中的一个值,永远不会改变。
如果这让您感到困扰(因为它没有明确记录),那么只需复制 HWND 并让线程访问它。
关于c++ - CWnd::GetSafeHwnd() 和 CWnd::m_hWnd 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9332153/