我在高度多线程的应用程序上面临无数崩溃。

通过阅读这些MSDN pagetechnical notethis 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英文。

09-30 15:47