关于_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的区别的更多相关文章

  1. _beginthreadex()和CreateThread()的区别

    在本例子中我们使用——beginThreadex这个函数,它和createThread的区别是: 为了方便管理,我么在使用该函数的时候可以把它的线程函数作为类成员,这也就需要在类中把该函数变成静态函数 ...

  2. CreateThread、_beginthreadex和AfxBeginThread 的区别

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

  3. AfxBeginThread和CreateThread具体区别

    1. 具体说来,CreateThread这个函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过程 中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁 ...

  4. VC++ AfxBeginThread 与 CreateThread 的区别

    简言之:AfxBeginThread是MFC的全局函数,是对CreateThread的封装.    CreateThread是Win32 API函数,前者最终要调到后者.具体说来,CreateThre ...

  5. 多线程 AfxBeginThread 与 CreateThread 的区别

      简言之:  AfxBeginThread是MFC的全局函数,是对CreateThread的封装. CreateThread是Win32 API函数,前者最终要调到后者. 1>.具体说来,Cr ...

  6. CreateThread、_beginthreadex和AfxBeginThread .

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

  7. Windows 多线程知识点汇总

    一.什么叫原子性? 答:一个操作不会被分成两个时间片来执行,不会刚执行到一半,由于时间片到了,CPU就跑去执行其他线程了.在多线程环境中对一个变量进行读写时,我们需要有一种方法能够保证对一个值的操作是 ...

  8. 多线程编程之Windows环境下创建新线程

    转自: http://www.cnblogs.com/lgxqf/archive/2009/02/10/1387480.html 在 Win32 API 中,创建线程的基本函数是 CreateThre ...

  9. 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别

    本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...

  10. (转)CreateThread与_beginthreadex本质区别

    本文将带领你与多线程作第一次亲密接触,并深入分析CreateThread与_beginthreadex的本质区别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...

随机推荐

  1. GitHub Universe 2023:AI 技术引领软件开发创新浪潮

    GitHub 是全球领先的软件开发和协作平台,数百万开发者和企业在此分享.学习和创建卓越的软件.同时 GitHub 处在 AI 技术前沿,通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命 ...

  2. STL容器详解

    详细总结STL 为什么C++比C更受人欢迎呢?除了C++ 的编译令人感到更舒适,C++的标准模板库(STL)也占了很重要的原因.当你还在用手手写快排.手写二叉堆,挑了半天挑不出毛病的时候,C++党一手 ...

  3. Qt官网开源最新版下载安装保姆级教程

    什么是Qt(了解请跳过) Qt 基本介绍 Qt 是一个跨平台C++图形用户界面应用程序开发框架. 有关 Qt 的详细介绍,可以参考这篇文章: Qt是什么?Qt简介(非常全面) - 李清龙的文章 - 知 ...

  4. 在Linux服务器上装jenkins(方式二:rpm包)

    官网下载jenkins https://www.jenkins.io/zh/download/ 上面比较慢,我们从清华大学开源镜像站下载安装包:https://mirrors.tuna.tsinghu ...

  5. 文心一言 VS 讯飞星火 VS chatgpt (167)-- 算法导论13.1 7题

    七.用go语言,试描述一棵含有 n 个关键字的红黑树,使其红色内部结点个数与黑色内部结点个数的比值最大.这个比值是多少? 该比值最小的树又是怎样呢?比值是多少? 文心一言: 红黑树是一种自平衡的二叉查 ...

  6. [笔记01]---solr

    什么是Solr 1.直接使用sql搜索存在的问题 大多数搜索引擎应用都必须具有某种搜索功能 搜索功能往往是巨大的资源消耗 它们由于沉重的数据库加载而拖垮你的应用的性能 所有我们一般在做搜索的时候 会把 ...

  7. STM32CubeMX教程3 GPIO输入 - 按键响应

    1.准备材料 开发板(STM32F407G-DISC1) ST-LINK/V2驱动 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) 2 ...

  8. 七天.NET 8操作SQLite入门到实战 - 第七天BootstrapBlazor UI组件库引入(1)

    前言 由于第七天Blazor前端页面编写和接口对接的内容比较的多,所以这一章节将会分为三篇文章来进行讲解,大家可以认为分为早.中.晚来进行阶段性学习,从而提高学习效率. 七天.NET 8 操作 SQL ...

  9. MySQL优化:12种提升SQL执行效率的有效方法

    在数据库管理和优化的世界里,MySQL作为一个流行的关系型数据库管理系统,其性能优化是任何数据密集型应用成功的关键.优化MySQL数据库不仅可以显著提高SQL查询的效率,还能确保数据的稳定性和可靠性. ...

  10. Java中单体应用锁的局限性&分布式锁

    互联网系统架构的演进 在互联网系统发展之初,系统比较简单,消耗资源小,用户访问量也比较少,我们只部署一个Tomcat应用就可以满足需求.系统架构图如下: 一个Tomcat可以看作是一个JVM进程,当大 ...