关于_beginthreadex和CreateThread的区别
关于_beginthreadex和CreateThread的区别
在 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()
关于_beginthreadex和CreateThread的区别的更多相关文章
- _beginthreadex()和CreateThread()的区别
在本例子中我们使用——beginThreadex这个函数,它和createThread的区别是: 为了方便管理,我么在使用该函数的时候可以把它的线程函数作为类成员,这也就需要在类中把该函数变成静态函数 ...
- CreateThread、_beginthreadex和AfxBeginThread 的区别
CreateThread._beginthreadex和AfxBeginThread 创建线程好几个函数可以使用,可是它们有什么区别,适用于什么情况呢?参考了一些资料,写得都挺好的,这里做一些摘抄和整 ...
- AfxBeginThread和CreateThread具体区别
1. 具体说来,CreateThread这个函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过程 中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁 ...
- VC++ AfxBeginThread 与 CreateThread 的区别
简言之:AfxBeginThread是MFC的全局函数,是对CreateThread的封装. CreateThread是Win32 API函数,前者最终要调到后者.具体说来,CreateThre ...
- 多线程 AfxBeginThread 与 CreateThread 的区别
简言之: AfxBeginThread是MFC的全局函数,是对CreateThread的封装. CreateThread是Win32 API函数,前者最终要调到后者. 1>.具体说来,Cr ...
- CreateThread、_beginthreadex和AfxBeginThread .
创建线程好几个函数可以使用,可是它们有什么区别,适用于什么情况呢?参考了一些资料,写得都挺好的,这里做一些摘抄和整合. [参考1]CreateThread, AfxBeginThread,_begin ...
- Windows 多线程知识点汇总
一.什么叫原子性? 答:一个操作不会被分成两个时间片来执行,不会刚执行到一半,由于时间片到了,CPU就跑去执行其他线程了.在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的操作是 ...
- 多线程编程之Windows环境下创建新线程
转自: http://www.cnblogs.com/lgxqf/archive/2009/02/10/1387480.html 在 Win32 API 中,创建线程的基本函数是 CreateThre ...
- 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别
本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...
- (转)CreateThread与_beginthreadex本质区别
本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...
随机推荐
- Redmi AC2100 路由器 官方固件允许IPv6外网访问下游设备
升级/降级 至 官方固件版本: 2.0.23 稳定版.操作入口在路由器常用设置-系统状态-升级检测处. 开启SSH权限.F12打开浏览器的开发者模式,并切换至终端选项卡,复制以下代码至终端处,并敲回车 ...
- [PostgreSQL]在group by查询下拼接列字符串
首先创建group_concat聚集函数: CREATE AGGREGATE group_concat(anyelement) ( sfunc = array_append, -- 每行的操作函数,将 ...
- MySQL-安全更新参数
版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 注意! 生产环境中,updata必须要加where条件 1.开启安全功能,会提示你加where,不加会提示语法不正确. ...
- Linux驱动开发笔记(五):驱动连接用户层与内核层的文件操作集原理和Demo
前言 驱动写好后,用户层使用系统函数调用操作相关驱动从而实现与系统内核的关联,本篇主要就是理解清楚驱动如何让用户编程来实现与内核的交互. 杂项设备文件操作集 cd /usr/src/linux ...
- IDEA提示Cannot resolve symbol 'String'
一.解决方案: 1.问题原因: 系统提示Cannot resolve symbol 'String',是由于没有正确导入JDK : 2.解决方案: 在project SDK中正确配置即可. 二.完成. ...
- vertx的学习总结2
一.什么是verticle verticle是vertx的基本单元,其作用就是封装用于处理事件的技术功能单元 (如果不能理解,到后面的实战就可以理解了) 二.写一个verticle 1. 引入依赖( ...
- springcloud+nacos项目启动后,登陆连接服务器时超时:Connection timed out no further information
问题现象:项目启动后,登陆连接服务器时超时:Connection timed out no further information 192.168.42.190:4004 原因:我的配置有问题,在na ...
- [洛谷P5368] [PKUSC2018] 真实排名
[PKUSC2018]真实排名 题目描述 小 C 是某知名比赛的组织者,该比赛一共有 \(n\) 名选手参加,每个选手的成绩是一个非负整数,定义一个选手的排名是:成绩不小于他的选手的数量(包括他自己) ...
- 3D 高斯喷溅 🤗 为什么图形永远不会相同
高斯喷溅 (Gaussian Splatting) 技术是一种翻天覆地的渲染手段,能够以 144 帧每秒的速度渲染出高质量的场景,这和传统的图形处理流程截然不同 这种将高斯数据转换成图像的过程,与训练 ...
- 华企盾DSC启动服务器提示“发生系统错误5”
解决方法:没有管理员权限 导致,需要以管理员权限运行服务器安装包,覆盖安装一下