如何避免使用createthread函数导致的内存泄露

如何避免使用createthread函数导致的内存泄露

ID:11209905

大小:138.90 KB

页数:10页

时间:2018-07-10

如何避免使用createthread函数导致的内存泄露_第1页
如何避免使用createthread函数导致的内存泄露_第2页
如何避免使用createthread函数导致的内存泄露_第3页
如何避免使用createthread函数导致的内存泄露_第4页
如何避免使用createthread函数导致的内存泄露_第5页
资源描述:

《如何避免使用createthread函数导致的内存泄露》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、如何避免使用CreateThread函数导致的内存泄露   前阵子翻了翻候杰老师翻译的那本Win32多线程的书,老书了,很经典。   书里提到,当使用C/C++的时候,有些情况下CreateThread会导致内存泄露,建议使用_beginthread和_beginthreadex。这种泄露网上也有不少帖子在讲。   事实上,这种泄露的可能是存在的,但是只要稍微注意一下,是可以找到方法避免的。  CreateThread导致内存泄露的原因    这得从C运行时库说起了。   VC运行时库,有一个宏errno,用来获得上一步操作的错误码,类似于Win32中的GetLastErro

2、r()函数。在多线程环境下,不同线程调用errno返回的都是caller线程的错误码,绝对不会混淆,这是因为使用了TLS技术。   TLS,ThreadLocalStorage,是用来存取线程相关数据的一种技术,在Win32中由操作系统的Tls*系列函数提供支持。例如,可以在程序开始的地方调用TlsAlloc()函数,获得一个TLSindex,这个index在进程范围内有效,然后可以创建n个线程,在每个线程中使用TlsSetValue(index,data)将线程相关数据和index关联起来,使用TlsGetValue(index)来获取当前线程和index相关联的的线程相关

3、数据。   查看msdn可以发现,Tls*函数的定义如下:[cpp]viewplaincopyprint?1.DWORD WINAPI TlsAlloc(void);  2.  3.BOOL WINAPI TlsSetValue(  4.  __in          DWORD dwTlsIndex,  5.  __in          LPVOID lpTlsValue  6.);  7.  8.LPVOID WINAPI TlsGetValue(  9.  __in          DWORD dwTlsIndex  10.);  11.  12.BOOL WINA

4、PI TlsFree(  1.  __in          DWORD dwTlsIndex  2.);     观察TlsSetValue/TlsGetValue的原型可以发现,与index关联的数据只能是void*类型,因此通常的做法是在线程开始的时候,为这个线程分配一块内存,用于存储所有与线程相关的数据,然后把这块内存的起始地址与index关联起来。如果这块内存在线程退出的时候没有释放掉,那就有内存泄露的危险。    回到errno,来看看C运行时库是如何实现errno的。   errno的声明和实现如下:[c-sharp]viewplaincopyprint?1./

5、* error.h - errno的声明 */  2._CRTIMP extern int * __cdecl _errno(void); 3.#define errno   (*_errno())  4.  5./* dosmap.c - errno的实现 */  6.int * __cdecl _errno(  7.        void  8.        )  9.{  10.    _ptiddata ptd = _getptd_noexit();  11.    if (!ptd) {  12.        return &ErrnoNoMem;  13. 

6、   } else {  14.        return ( &ptd->_terrno );  15.    }  16.}     观察_errno的代码,函数首先调用了_getptd_noexit()函数,这个函数的代码如下:[cpp]viewplaincopyprint?1./* tiddata.c - _getptd_noexit()实现 */  2._ptiddata __cdecl _getptd_noexit (  3.        void  4.        )  5.{  6.    _ptiddata ptd;  7.    DWORD   T

7、L_LastError;  8.  9.    TL_LastError = GetLastError();  10.  11.#ifdef _M_IX86  12.  13.    /* 14.     * Initialize FlsGetValue function pointer in TLS by calling __set_flsgetvalue() 15.     */  16.  17.    if ( (ptd = (__set_flsgetvalue())(__flsindex)) 

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。