c++ - CWnd::GetSafeHwnd() 和 CWnd::m_hWnd 是线程安全的吗?

标签 c++ multithreading winapi thread-safety thread-local-storage

我在一个高度多线程的应用程序上遇到了无数次崩溃。

阅读这些 MSDN page , technical notethis 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 并让线程访问它。

附言Here's the article you linked to英文。

关于c++ - CWnd::GetSafeHwnd() 和 CWnd::m_hWnd 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9332153/

相关文章:

c++ - 将事件/ Action 连接到 QPlainTextEdit

c++ - 将结构写入和读取文件

java - 如果我在单核机器上运行应用程序,volatile 关键字是否有用?

java - 什么是java信号调度线程?

c++ - 在 Visual C++ 中访问 MONITORINFOEX 值

c# - SetWindowsHookEx with WH_MOUSE_LL 减慢鼠标几秒钟

c++ - sscanf_s 无法从字符串中找到所有值

c++ - wstring 上的 Intellisense 显示 : npos = 18446744

c++ - 按字母顺序排序结构数组

c - jemalloc 和 tcmalloc 如何跟踪线程?