首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CWnd::GetSafeHwnd()和CWnd::m_hWnd ThreadSafe吗?

CWnd::GetSafeHwnd()和CWnd::m_hWnd ThreadSafe吗?
EN

Stack Overflow用户
提问于 2012-02-17 16:43:17
回答 3查看 9.3K关注 0票数 8

我正面临大量崩溃的应用程序,这是严重的多线程。

通过阅读这些MSDN 页面技术说明这篇关于TLS的文章,我了解到CWnd对象在Thread (TLS,这是一个依赖线程的内存访问)中映射到HWND。

我打算将所有看起来像CWnd线程的远程访问解耦,并将其转换为HWND引用,然后使用::PostMessage作为通信端口。

但我的一位同事确实坚持我只需将CWnd*保留在外国人线程中,采用::PostMessage策略ok,而在外部线程中使用CWnd::GetSafeHwnd()pMyCWnd->m_hWnd来恢复本机HWND

我一直在争论nowhere --我看到GetSafeHwnd()是线程安全的,而CWnd objet在TLS中,它在另一个线程中的值是不同的。

我错了?MSDN显然使用了术语意外结果

对于从创建者线程调用外部线程中的CWnd::GetSafehwnd()pMyCWnd->m_hWnd,您的观点是什么?

您是否有任何MSDN文档说明这是否安全。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-17 17:18:46

CWnds不是映射到HWND;HWND映射到CWnds,这是在每个线程的基础上进行的。CWnd对象不在TLS中(如何工作?)但是临时CWnd对象是每个线程创建的。

从错误的线程访问临时CWnd对象肯定是个坏主意(原因由Mark描述)。

但是,如果您有一个永久的CWnd对象(例如,代表应用程序的主窗口),那么一旦创建了它,从任何线程访问m_hWnd成员都没有问题。它只是一个永远不变的记忆中的值。

如果这让您感到困扰(因为它没有显式的文档化),那么只需创建HWND的一个副本,并让线程访问它。

P.S. 这是你链接到的文章 (英文)。

票数 10
EN

Stack Overflow用户

发布于 2012-02-17 16:57:53

GetSafeHwnd只是一个包装器,它检查this是否为NULL,如果不是返回m_hWnd,如果为NULL则返回m_hWnd。它不会比m_hWnd本身更安全。

创建临时CWnd*时,MFC将在它认为安全的点销毁它,例如下一次通过消息循环。如果您有使用MFC的多个线程,那么您的临时对象可能会在您仍在使用时被销毁。您无法从线程中检测到此错误。

票数 5
EN

Stack Overflow用户

发布于 2012-02-17 16:49:35

如果您有一个多线程应用程序,其中多个线程都试图同时访问HWND,我认为您有一个设计问题。您不能限制您的线程进行计算,并处理主线程上的UI问题吗?这是一个好的多线程应用程序的典型设计。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9332153

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档