我在高度多线程的应用程序上面临无数崩溃。
通过阅读这些MSDN page,technical note和this article on TLS,我了解到CWnd
对象已映射到线程本地Storgae(TLS,这是线程相关的内存访问)中的HWND。
我将解耦所有看起来像CWnd线程远程访问的东西,并将其转换为HWND
引用,然后将::PostMessage
用作通信端口。
但是我的一位同事真的坚持说,我只是将CWnd*
保留在外来线程中,采用::PostMessage
策略正常,但在外来线程中使用CWnd::GetSafeHwnd()
或pMyCWnd->m_hWnd
来恢复本地HWND
。
我一直在争论在任何地方我已经看到GetSafeHwnd()
是线程安全的,并且CWnd
对象在TLS中,它在另一个线程中的值是不同的。
我错了 ? MSDN显然在使用术语意外结果。
关于从创建者线程在外线程中调用CWnd::GetSafehwnd()
或pMyCWnd->m_hWnd
,您有什么看法?
您是否有任何MSDN文档声明这是否安全。
最佳答案
CWnd未映射到HWND; HWND映射到CWnd,并且这是在每个线程的基础上发生的。 CWnd对象不在TLS中(它将如何工作?),但每个线程都会创建临时CWnd对象。
从错误的线程访问临时CWnd对象绝对不是一个好主意(出于Mark Ransom所述的原因)。
但是,如果您有一个永久性的CWnd对象(例如,代表应用程序的主窗口),那么一旦创建了该对象,就可以从任何线程访问m_hWnd成员都没有问题。这只是内存中永远不变的值。
如果这麻烦您(因为它没有明确记录),则只需制作HWND的拷贝,然后让线程访问该拷贝。
P.S. Here's the article you linked to英文。