我正面临大量崩溃的应用程序,这是严重的多线程。
通过阅读这些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文档说明这是否安全。
发布于 2012-02-17 17:18:46
CWnds不是映射到HWND;HWND映射到CWnds,这是在每个线程的基础上进行的。CWnd对象不在TLS中(如何工作?)但是临时CWnd对象是每个线程创建的。
从错误的线程访问临时CWnd对象肯定是个坏主意(原因由Mark描述)。
但是,如果您有一个永久的CWnd对象(例如,代表应用程序的主窗口),那么一旦创建了它,从任何线程访问m_hWnd成员都没有问题。它只是一个永远不变的记忆中的值。
如果这让您感到困扰(因为它没有显式的文档化),那么只需创建HWND的一个副本,并让线程访问它。
P.S. 这是你链接到的文章 (英文)。
发布于 2012-02-17 16:57:53
GetSafeHwnd只是一个包装器,它检查this是否为NULL,如果不是返回m_hWnd,如果为NULL则返回m_hWnd。它不会比m_hWnd本身更安全。
创建临时CWnd*时,MFC将在它认为安全的点销毁它,例如下一次通过消息循环。如果您有使用MFC的多个线程,那么您的临时对象可能会在您仍在使用时被销毁。您无法从线程中检测到此错误。
发布于 2012-02-17 16:49:35
如果您有一个多线程应用程序,其中多个线程都试图同时访问HWND,我认为您有一个设计问题。您不能限制您的线程进行计算,并处理主线程上的UI问题吗?这是一个好的多线程应用程序的典型设计。
https://stackoverflow.com/questions/9332153
复制相似问题