在 Win32 API 中,创建线程的基本函数是 CreateThread,而 _beginthread(ex) 是
C++ 运行库的函数。为什么要有两个呢?因为C++ 运行库里面有一些函数使用了全局
量,如果使用 CreateThread 的情况下使用这些C++ 运行库的函数,就会出现不安全
的问题。而 _beginthreadex 为这些全局变量做了处理,使得每个线程都有一份独立
的“全局”量。

所以,如果你的编程只调用 Win32 API/SDK ,就放心用 CreateThread;如果要用到
C++ 运行时间库,那么就要使用 _beginthreadex ,并且需要在编译环境中选择 Use
MultiThread Lib/DLL。

C++ 运行期库有两个创建线程的函数,另一个是 _beginthread, 它们两者的区别请
自己去看MSDN:

通常他们的解释都是这容易造成内存泄漏。这个解释本身是没有错的,但是解释得不够完全和详 细。以至于造成很多新手盲目的信任了那句话,在那里都是用_beginthreadex函数,或者是装作没有看到使用CreateThread函数。曾经 有一段时间我也对这个问题很是困惑,不知道到底用那个才是对的。因为我不止一次在很多权威性的代码中看到对CreateThread函数的直接调用。难道 是权威错了?? 抱着怀疑的态度查找了大量的资料和书籍,终于搞明白了这个问题的关键所在,在此做个说明,算是对那句话的一个完善。

关于_beginthreadex和CreateThread的区别我就不做说明了,这个很 容易找到的。我们只要知道一个问题:_beginthreadex是一个C运行时库的函数,CreateThread是一个系统API函 数,_beginthreadex内部调用了CreateThread。只所以所有的书都强调内存泄漏的问题是因为_beginthreadex函数在创 建线程的时候分配了一个堆结构并和线程本身关联起来,我们把这个结构叫做tiddata结构,是通过线程本地存储器TLS于线程本身关联起来。我们传入的 线程入口函数就保存在这个结构中。tiddata的作用除了保存线程函数入口地址之外,还有一个重要的作用就是:C运行时库中有些函数需要通过这个结构来 保存和获取一些数据,比如说errno之类的线程全局变量。这点才是最重要的。

当一个线程调用一个要求tiddata结构的运行时库函数的时候,将发生下面的情况:

运行时库函数试图TlsGetv alue获取线程数据块的地址,如果没有获取到,函数就会 现场分配一个 tiddata结构,并且和线程相关联,于是问题出现了,如果不通过_endthreadex函数来终结线程的话,这个结构将不会被撤销,内存泄漏就会出 现了。但通常情况下,我们都不推荐使用_endthreadex函数来结束线程,因为里面包含了ExitThread调用。

找到了内存泄漏的具体原因,我们可以这样说:只要在创建的线程里面不使用一些要求tiddata结构的运行时库函数,我们的内存时安全的。所以,前面说的那句话应该这样说才完善:

“绝对不要调用系统自带的CreateThread函数创建新的线程,而应该使用_beginthreadex,除非你在线程中绝不使用需要tiddata结构的运行时库函数”

这个需要tiddata结构的函数有点麻烦了,在侯捷的《win32多线程程序设计》一书中这样说到:

”如果在除主线程之外的任何线程中进行一下操作,你就应该使用多线程版本的C runtime library,并使用_beginthreadex和_endthreadex:

1 使用malloc()和free(),或是new和delete

2 使用stdio.h或io.h里面声明的任何函数

3 使用浮点变量或浮点运算函数

4 调用任何一个使用了静态缓冲区的runtime函数,比如:asctime(),strtok()或rand()

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhuzhubin/archive/2009/06/21/4287446.aspx

Creatthread _Beginthread _Beginthreadex相关推荐

  1. 采用_beginthread/_beginthreadex函数创建多线程

    1.CRT简介: CRT: (C Runtime Library)即C运行时库,是系统运行的基础,包含了c常用的函数集(如:printf,malloc,strcpy等),为运行main做了初始化环境变 ...

  2. VC++ MSDN中的 _beginthreadex与_endthreadex 的使用例子

    1._beginthread, _beginthreadex . 用于创建线程 [cpp] view plaincopy uintptr_t _beginthread( void( *start_ad ...

  3. CreateThread、_beginthread与AfxBeginThread的区别及其注意事项

    在windows下一般由以下三种方式来进行线程操作: 1.通过CreateThread(),对应线程结束函数ExitThread(): 2.通过_beginthread(),对应线程结束函_endth ...

  4. CreateThread、_beginthreadex和AfxBeginThread 的区别

    CreateThread._beginthreadex和AfxBeginThread 创建线程好几个函数可以使用,可是它们有什么区别,适用于什么情况呢? 参考了一些资料,写得都挺好的,这里做一些摘抄和 ...

  5. _beginthreadex和_endthreadex源码概览

    _beginthreadex是ucrt提供的创建线程的接口,_beginthreadex在内部调用了windows系统提供的CreateThread接口,_endthreadex的作用是显式的结束线程 ...

  6. c++创建线程:CreateThread 和pthread_create和 _beginthreadex

    CreateThread 在 Windows 中,您可以使用 CreateThread() 来创建线程,创建的线程在调用进程的虚拟地址空间中运行.  HANDLE CreateThread(   LP ...

  7. 程序员的自我修养--链接、装载与库笔记:运行库

    1. 入口函数和程序初始化 程序从main开始吗?:操作系统装载程序之后,首先运行的代码并不是main的第一行,而是某些别的代码,这些代码负责准备好main函数执行所需要的环境,并且负责调用main函 ...

  8. Win32 多线程的创建方法,区别和联系

    2019独角兽企业重金招聘Python工程师标准>>> Win32多线程的创建方法主要有: CreateThread() _beginthread()&&_begin ...

  9. 基于MFC串口编程和曲线图绘制(visual studio2008,Teechart绘图控件)的程序总结

    前言 今年刚进入公司按经理的要求为底盘测控机写了一个小小的console.这也是第一次教认真的完成整个程序的编写.程序不大,所用技术比较基础也不前卫,属于初级程序员的练手程序(知识的整理和搬运).虽然 ...

最新文章

  1. 关于HTML代码的转义
  2. java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作
  3. 鸢尾花分类_K近邻(分类通用 数据挖掘入门与实践-实验4)
  4. 大白话5分钟带你走进人工智能-第二十六节决策树系列之Cart回归树及其参数(5)...
  5. html中scope的作用,AngularJS 作用域(Scope)
  6. linux系统安装arcsde,Linux操作系统安装ArcSDE10
  7. 前置仓没活路?盒马mini要做行业终极目标还为时尚早
  8. 接口测试工具ApiPost 发送报 socket hangup 的解决方案
  9. 【转载】Android面试题集
  10. 于的繁体字有几种写法_于字书法繁体字怎么写
  11. C语言生成负指数分布,泊松分布与负指数分布的关系
  12. python俄罗斯方块思路_python实现俄罗斯方块小游戏
  13. 梦殇 chapter one
  14. 使用VMware虚拟机通过Panabit抓取爱快虚拟机PPPoE报文
  15. 计算机组成与系统结构期末复习 第二章 2.2
  16. SpringBoot、EasyPoi、Echarts 实现文档导入、出、图表显示 (饼状图、柱状图) 保姆级教程
  17. 脑裂是什么,zk是如何解决脑裂问题的
  18. 如何实现超大文件上传?
  19. webRTC(二十四):web远程多台android的实现
  20. MSP430异步通信(发送)不阻塞CPU,含注释

热门文章

  1. Redis Psubscribe 命令
  2. 【Linux】Linux 管道命令Cut、sort、wc、uniq、tee、tr【一】
  3. LeetCode149、最后一块石头的重量 II
  4. 70后 80后 90后的20个经典差别!
  5. 哨兵机器人钢力士_X战警VS哨兵机器人场景雕像 魄力十足售价3万
  6. 单反相机镜头术语解释
  7. 做不到数据决策,别说懂数据分析。
  8. cdn缓存数据部署php,CDN 缓存规则设置
  9. JDK1.8源码分析:LinkedHashMap与LRU缓存设计思路
  10. 【缘起•看见】公益捐书宝鸡第七场——走进岐山县凤鸣镇杏园逸夫小学