是CWnd :: GetSafeHwnd()和CWnd :: m_hWnd ThreadSafe?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是CWnd :: GetSafeHwnd()和CWnd :: m_hWnd ThreadSafe?相关的知识,希望对你有一定的参考价值。
我面临着大量多线程应用程序的大量崩溃。
阅读这些MSDN page,technical note和this article on TLS,我已经了解到CWnd
对象被映射到Thread Local Storgae中的HWND(TLS,这是一个线程依赖的内存访问)。
我打算将看起来像CWnd线程远程访问的所有内容分离,并将其转换为HWND
引用,然后使用::PostMessage
作为通信端口。
但是我的一位同事真的坚持认为我只是将CWnd*
保留在外国人的线程中,采用::PostMessage
政策确定,但在外国线程中使用CWnd::GetSafeHwnd()
或pMyCWnd->m_hWnd
以便恢复原生的HWND
。
我一直在争论说,我没有看到GetSafeHwnd()
是线程安全的,并且CWnd
objet在TLS中,它在另一个线程中的价值是不同的。
我错了 ? MSDN显然使用了术语“意外结果”。
你有什么观点,关于从创建者线程中调用外部线程中的CWnd::GetSafehwnd()
或pMyCWnd->m_hWnd
?
您是否有任何MSDN文档说明这是否安全。
CWnds未映射到HWND; HWND映射到CWnds,这是在每个线程的基础上发生的。 CWnd对象不在TLS中(如何工作?)但是每个线程创建临时CWnd对象。
从错误的线程访问临时CWnd对象绝对是个坏主意(出于Mark Ransom所描述的原因)。
但是,如果你有一个永久的CWnd对象(比如你的应用程序的主窗口),那么,一旦创建它,从任何线程访问m_hWnd成员都没有问题。它只是内存中永不改变的值。
如果这给您带来麻烦(因为它没有明确记录),那么只需复制HWND并让线程访问它。
附: Here's the article you linked to英文。
GetSafeHwnd只是一个包装器,用于检查this
是否为NULL,如果不是则返回m_hWnd
,如果是,则返回NULL。它不会比m_hWnd
本身更安全。
当您创建临时CWnd *时,MFC将在它认为安全的位置销毁它,例如下一次通过消息循环。如果你有多个线程使用MFC,那么你的临时对象可能会在你仍在使用时被销毁。您可以从线程中执行任何操作都无法检测到此错误。
如果你有一个多线程应用程序,其中多个线程都试图一次访问HWND,听起来像你有一个设计问题。你不能限制你的线程进行计算,并处理主线程上的UI问题吗?这是一个优秀的多线程应用程序的典型设计。
以上是关于是CWnd :: GetSafeHwnd()和CWnd :: m_hWnd ThreadSafe?的主要内容,如果未能解决你的问题,请参考以下文章