询问者
CImage的多线程使用问题

问题
-
关键点在于CImage中使用了静态成员:
static CDCCache s_cache;
CImage的GetDC调用了s_cache的GetDC,s_cache的GetDC如下:
inline HDC CImage::CDCCache::GetDC() throw() { HDC hDC; for( int iDC = 0; iDC < CIMAGE_DC_CACHE_SIZE; iDC++ ) { hDC = static_cast< HDC >( InterlockedExchangePointer( reinterpret_cast< void** >(&m_ahDCs[iDC]), NULL ) ); if( hDC != NULL ) { return( hDC ); } } hDC = ::CreateCompatibleDC( NULL ); return( hDC ); }
即,当有缓存的HDC时,并没有直接创建而是返回上一次创建并且被Release的HDC。ReleaseDC如下:
inline void CImage::CDCCache::ReleaseDC(_In_ HDC hDC) throw() { for( int iDC = 0; iDC < CIMAGE_DC_CACHE_SIZE; iDC++ ) { HDC hOldDC; hOldDC = static_cast< HDC >( InterlockedExchangePointer( reinterpret_cast< void** >(&m_ahDCs[iDC]), hDC ) ); if( hOldDC == NULL ) { return; } else { hDC = hOldDC; } } if( hDC != NULL ) { ::DeleteDC( hDC ); } }
当多个线程中使用CImage这个类时,就可能出现一个线程创建出来的HDC在Release之后,被缓存到m_ahDCs,而另外一个线程中再GetDC时可能就取到这个HDC了。
在MSDN关于
HDC CreateCompatibleDC( _In_ HDC hdc );
有这样的说明:
If hdc is NULL, the thread that calls CreateCompatibleDC owns the HDC that is created. When this thread is destroyed, the HDC is no longer valid. Thus, if you create the HDC and pass it to another thread, then exit the first thread, the second thread will not be able to use the HDC.
但是在CImage中并没有提到关于多线程使用要注意的问题,我想请教一下CImage是否因此无法适用于多线程环境?
全部回复
-
你好:
据我所知,如果创建一个兼容性DC估计可以解决这个问题。
你看下下面这个文章,希望有帮助。
GDI 总结三: CImage类使用
- 已编辑 Anna CcModerator 2014年6月11日 3:40
-
你好:
据我所知,如果创建一个兼容性DC估计可以解决这个问题。
你看下下面这个文章,希望有帮助。
GDI 总结三: CImage类使用
您好,我看了一下您给的文章。文章里面采用了一个MemDC,并且最终绘制到了MemDC。但是这个MemDC创建时采用的参数仍旧是通过CImage的GetDC获取到的。如果在多线程环境里,GetDC获取到的HDC可能是无效的话,那还能保证通过这个HDC创建出来的MemDC一定有效么?