Is CWnd::GetSafeHwnd() and CWnd::m_hWnd ThreadSafe?
Is CWnd::GetSafeHwnd() and CWnd::m_hWnd ThreadSafe?
我在一个多线程应用程序上遇到了许多崩溃。
阅读这些MSDN页面、技术说明和这篇关于TLS的文章,我了解到CWnd
对象被映射到线程本地Storgae(TLS,这是一种依赖于线程的内存访问)中的HWND。
我打算将所有看起来像CWnd线程远程访问的东西解耦,并将其转换为HWND
引用,然后使用::PostMessage
作为通信端口
但我的一位同事真的坚持认为,我只需要在外部线程中保留CWnd*
,采用::PostMessage
策略就可以了,但在外部线程使用CWnd::GetSafeHwnd()
或pMyCWnd->m_hWnd
,以便恢复本地HWND
。
我一直在争论where我已经看到GetSafeHwnd()
是线程安全的,而CWnd
对象在TLS中,它在另一个线程中的值是不同的。
我错了?MSDN显然使用了意外结果这一术语。
关于从创建者线程在外线程中调用CWnd::GetSafehwnd()
或pMyCWnd->m_hWnd
,您的观点是什么?
你有没有MSDN文档说明这是否安全。
CWnd未映射到HWND;HWND被映射到CWnds,这是在每个线程的基础上发生的。CWnd对象不在TLS中(如何工作?),但临时CWnd对象是每个线程创建的。
从错误的线程访问临时CWnd对象肯定是个坏主意(原因由Mark Ransom描述)。
然而,如果你有一个永久的CWnd对象(比如说,代表你的应用程序的主窗口),那么一旦创建了它,从任何线程访问m_hWnd成员都不会有任何问题。这只是记忆中的一个永远不会改变的价值。
如果这让您感到困扰(因为它没有明确记录),那么只需制作HWND的副本,并让线程访问它。
附言:这是你链接到的英文文章。
GetSafeHwnd只是一个包装器,它检查this
是否为NULL,如果不是,则返回m_hWnd
,如果是,则返回NULL。它不会比m_hWnd
本身更线程安全。
当您创建临时CWnd*时,MFC会在它认为安全的地方销毁它,例如下一次通过消息循环。如果您有多个使用MFC的线程,那么您的临时对象可能会在您仍在使用时被销毁。您无法从线程中检测到此错误。
如果您有一个多线程应用程序,其中多个线程都试图同时访问HWND,那么在我看来,您似乎有设计问题。难道不能将线程限制在计算上,并在主线程上处理UI问题吗?这是一个好的多线程应用程序的典型设计。
- 获取 SFML 窗口的 HWND 和高可用性?
- 如何获取边缘窗口句柄 (HWND)?
- 标识符"hWnd"未定义
- Win32 API - HWND "{unused = ???} Unable to read memory"错误
- 通过比较 GetCurrentProcessId();获得正确的 HWND
- 我需要通过窗口句柄(HWND)获取文件,我该怎么办?
- 由于选项卡顺序的原因,鼠标光标总是得到错误的hwnd-MFC应用程序
- 在库中创建CWnd
- 枚举 HWND 属性 c++
- 在C++中将 HWND 转换为十六进制字符串
- 从 HWnd 获得永久 CWnd
- 创建D2D1工厂和HWND渲染目标
- 获取我单击的窗口的 HWND
- hwnd 设置高位是否正常
- 设置 VLC drawable-hwnd 仍会创建一个新窗口
- 如何从其HWND上构建窗口的技术
- 从 HWND 到应用程序名称
- 设置 HWND TXT 颜色
- EnableWindow(hWnd, false) 不禁用键盘输入
- 将 int 转换为 HWND 时的警告