关于_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 ...
随机推荐
- BFS广搜小谈
个人认为BFS比DFS难度要大一些,所以来这里做个笔记. 比较可怜的是本蒟蒻并没有找到BFS这个东西解题有什么规律,所以我只能粘上3个代码. 模板 当然一个差不多点儿的模板还是要有的. //模板1 # ...
- AcWing 368. 银河
原本是一个差分约束的问题,但是由于数据过大可能导致\(spfa\)被卡,而由于这道题的边权只有\(0,1\)两种,比较特殊,所以使用\(tarjan\)求连通分量,缩点,递推的方式也能完成,时间复杂度 ...
- 学生开发者勇担青年使命,用AI守护少数人的“视界”
本文分享自华为云社区<[先锋开发者云上说]学生开发者勇担青年使命,用AI守护少数人的"视界">,作者:华为云社区精选 . 青年动人之处,在于他们的勇气,和非凡的创造探索 ...
- MySQL-char与 varchar 的区别?
版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 1.共同点: 都是字符串类型 2.不同点: ①.char类型是定长数据类型.,对于数据插入的速度比较块,在有大量插入需 ...
- [Codechef REBXOR]Nikitosh and xor (Trie,异或)
题目传送门 分析:首次考虑暴力枚举 \(l_{1},r_{1},l_{2},r_{2}\),配合前缀和时间复杂度 \(O(N^{4})\),需要想办法优化.对于这种两段区间不重合的,我们考虑枚举两段区 ...
- C#12新功能有哪些?
前言 作为.NET 8发布会的一部分,微软于11月14日发布了C#12的新功能,这也是目前.NET的最新版本.正如之前公布的那样,最显著的改进包括了集合表达式.主构造函数.任何类型的别名以及lambd ...
- [AGC031E] Snuke the Phantom Thief
Problem Statement A museum exhibits $N$ jewels, Jewel $1, 2, ..., N$. The coordinates of Jewel $i$ a ...
- Cocos-JS HTTP网络请求
网络结构 网络结构是网络构建方式,目前流行的有客户端服务器结构(C/S结构)和点对点(P2P)结构网络. 客户端服务器结构(C/S结构) 这种结构又被称为Clicent/Server结构,它是一种主从 ...
- flask的cookie和session会话保持
Cookie 获取请求cookie 通过请求对象中的cookies属性可以获取cookie. 实例: from flask import Flask, request @app.route(" ...
- ModuleNotFoundError: No module named '_pytest.resultlog'
新环境运行Python时报错 ModuleNotFoundError: No module named '_pytest.resultlog' 上网查,看到解决方法 https://www.cnbl ...