码迷,mamicode.com
首页 > 编程语言 > 详细

MFC多线程内存泄漏问题&解决方法

时间:2014-10-26 17:01:39      阅读:855      评论:0      收藏:0      [点我收藏+]

标签:c++   多线程   mfc   

     在用visual studio进行界面编程时(如MFC),前台UI我们可以通过MFC的消息循环机制实现。而对于后台的数据处理,我们可能会用到多线程来处理。那么对于大多数人(尤其是我这种菜鸟),一个比较快捷的方法便是选择MFC多线程:AfxBeginThread或者CreateThread来进建立多线程。当一两个线程还是可以得,当有3个或者3个以上的线程出现时,极可能出现内存泄漏。原因分析如下:

CWinThread的多线程不安全性:

     因为 CWinThread 会调用_beginthreadex来初始化C运行时库,而同样地,如果线程被强制终止(TerminateThread),因为  TerminateThread是不会去管 C运行时库的,从而,导致部分和引用计数相关的C运行时数据的内存释放出现问题。最典型的特征是,使用STL库的静态变量 内存回收将出错,从而导致进程退出时误报异常。
此外,如果AfxBeginThread频繁进行回收和分配线程,如果不严格操作,也会导致崩溃。VC6中,应该严格控制STL库的使用,避免MFC库和STL库并存,否则,会有很多问题。

原因:

     AfxBeginThread在内部直接调用了CreateThread创建线程而不是c语言下推荐的beginthreadex函数,而这两个函数是有区别的,主要是c运行库的历史遗留问题造成的。

     在多线程环境中存在问题的C/C++运行期库变量和函数包括errno、_doserrno、strtok、_wcstok、strerror、_strerror、tmpnam、tmpfile、asctime、_wasctime、gmtime、_ecvt和_fcvt等。
若要使多线程C/C++程序能够正确地运行,必须创建一个数据结构,并将它与使用C/C++运行期库函数的每个线程关联起来。当你调用C / C + +运行期库时,这些函数必须知道查看调用线程的数据块,这样就不会对别的线程产生不良影响。那么系统是否知道在创建新线程时分配该数据块呢?回答是它不知道。系统根本不知道你得到的应用程序是用C/C++编写的,也不知道你调用函数的线程本身是不安全的。问题在于你必须正确地进行所有的操作。若要创建一个新线程,绝对不要调用操作系统的CreateThread函数,必须调用C/C++运行期库函数_beginthreadex。
下面是关于_beginthreadex的一些要点:
      每个线程均获得由C/C++运行期库的堆栈分配的自己的tiddata内存结构。(tiddata结构位于Mtdll.h文件中的Visual C++源代码中)。传递给_beginthreadex的线程函数的地址保存在tiddata内存块中。传递给该函数的参数也保存在该数据块中。_beginthreadex确实从内部调用CreateThread,因为这是操作系统了解如何创建新线程的
唯一方法。###可以看出调用_beginthreadex时分配了额外的内存空间。

    如果调用CreateThread,而不是调用C / C + +运行期库的_beginthreadex来创建新线程,将会发生什么情况。当一个线程调用要求tiddata结构的C / C + +运行期库函数时,将会发生下面的一些情况(大多数C / C + +运行期库函数都是线程安全函数,不需要该结构)。首
先, C / C + +运行期库函数试图(通过调用TlsGetValue)获取线程的数据块的地址。如果返回
NULL作为tiddata块的地址,调用线程就不拥有与该地址相关的tiddata块。这时,C / C + +运行期库函数就在现场为调用线程分配一个tiddata块,并对它进行初始化。然后该tiddata块(通过TlsSetValue)与线程相关联。
###_beginthreadex相对应的推出函数是_endthreadex,这个函数会释放tiddata的内容。
---------------------------
    如果你采用CreateThread创建线程,而你没有使用上面所提到的那些特殊运行期库的话,也是不会出现问题的;如果一定要用那些运行库的话就最好调用_beginthreadex 这个api来创建线程,否则tiddata数据块就无法撤销,引起内存泄漏。

你可以参照_beginthreadex源代码来进行理解。

引申阅读:

关于_beginthreadex和CreateThread的区别


MFC多线程内存泄漏问题&解决方法

标签:c++   多线程   mfc   

原文地址:http://blog.csdn.net/wangkr111/article/details/40477145

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!