CreateThread与_beginthreadex的区别

原创 2017年01月03日 15:23:01

一  为什么不直接使用CreateThread,而要使用运行库函数_beginthreadex函数?
1  CreateThread不会在创建线程之前申请一个_tiddata结构内存块,当一个线程调用一个需要_tiddata结构的C/C++运行库函数(例如errno, strtok, _gmtime等)时,虽然C/C++运行库函数会为主调函数申请并初始化一个_tiddata块,但是在线程退出的时候,如果不是调用_endthreadex函数的话,_tiddata块将不能被释放,从而导致内存泄露。(当模块链接到C/C++运行库的DLL版本时,这个库会在线程终止时收到一个DLL_THREAD_DETACH通知,然后会执行释放_tiddata块)

2  如果线程使用了C/C++运行库的signal函数(该函数用于设置中断信号处理函数,比如可以使用此函数屏蔽CTRL+C,更多介绍可参阅MSDN),则整个进程会异常退出。因为CreateThread创建的线程其结构化异常处理帧(SEH)没有设置,导致程序不能处理异常。

二  _beginthreadex函数都干了啥
1  对照前面第一点中提到的CreateThread的隐患,_beginthreadex都做了相应的处理,首先_beginthreadex函数会申请_tiddata数据结构块,然后会将要创建线程的入口点和参数都设置到该_tiddata数据结构中。


2  _beginthreadex内部确实调用了CreateThread这一系统API,因为这是操作系统创建新线程的唯一方法。
但是调用CreateThread时,所给的新线程入口点是_threadstartex,而不是外部由程序员提供的线程入口地址,同时,传递给CreateThread的参数也不是外部由程序员提供的参数,而是_threadstartex申请的_tiddata数据结构块。所以,接下来的工作都将转入到_threadstartex函数中。

三  _threadstartex函数做了什么工作
1  首先使用TlsSetVlue函数将_tiddata结构和线程关联起来。
2  初始化浮点操作支持。
3  设置SEH链,捕捉C++异常,例如在第一点中提到的C/C++运行库的signal函数,需要异常处理支持。
4  以上工作就绪后,会调用保存在_tiddata中由外部程序员提供的线程入口函数,并传入保存在_tiddata中的参数,这样就启动了线程代码。
5  该函数将一直等待线程的结束,当线程返回时,调用_endthreadex函数,在_endthreadex内部通过_getptd和_freeptd释放掉_tiddata结构的内存。_endthreadex函数最终会调用系统的ExitThread API(这时候调用该函数已经是安全的了,因为_tiddata内存已经释放)。

四  为什么不应该调用ExitThread函数
这一点在第三点中已经说明了,直接调用ExitThread函数会导致_tiddata内存无法释放,如果不得已,外部必须要结束一个线程,可以调用_endthreadex来结束线程,_endthreadex会释放_tiddata内存块。

五  不应该使用_beginthread、_endthread函数。
_beginthread的参数缺少安全描述符. 而且它是创建线程的时候先以挂起状态创建 (CreateThread会填充ptd->_thandle和ptd->_tid) 然后再ResumeThread
_beginthread是根据传进来的参数创建线程,此外,两者失败返回值不同,ex版本的与Windows API CreateThread返回值是一直的,这也是提倡使用后者的原因之一。

版权声明:本文为博主原创文章,未经博主允许不得转载。

CreateThread与_beginthreadex本质区别

  • 2014年09月04日 12:33
  • 161KB
  • 下载

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

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

多线程一 CreateThread与_beginthreadex的本质区别

1、尽量使用_beginthreadex()来代替使用CreateThread(),为什么?        _beginthreadex()函数在创建新线程时会分配并初始化一个_tiddata块。这...

秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别

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

_beginthreadex与CreateThread区别与联系

关于这两个函数的区别,可以参考《Windows 核心编程(第五版)》的第六章"线程基础",这篇文章的思想多数来源于此,我只是作了一些整理。 线程对于初学者还说可能觉得很高深,这可以理解。对于某些有经...

CreateThread、_beginthreadex和AfxBeginThread 的区别

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

windows 多线程: CreateThread、_beginthread、_beginthreadex、AfxBeginThread 的区别

推荐参考博客:秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别 CreateThread:Windows的API函数(SDK函数...

_beginthreadex与createthread和AfxBeginThread的区别

1、不要在一个MFC程序中使用_beginthreadex()或CreateThread()。  这句话的意思是由于AfxBeginThread()是MFC封装的启动线程的函数,里面包含了很多和MF...
  • sptoor
  • sptoor
  • 2011年11月21日 11:02
  • 2095

CreateThread, AfxBeginThread,_beginthread, _beginthreadex的区别

CreateThread是Windows的API函数(SDK函数的标准形式,直截了当的创建方式,任何场合都可以使用),提供操作系统级别的创建线程的操作,且仅限于工作者线程。不调用MFC和RTL的函数时...

_beginthreadex()与CreateThread()函数的区别

CreateThread()函数是Windows提供的API接口,在C/C++语言另有一个创建线程的函数_beginthreadex(),在很多书上(包括《Windows核心编程》)提到过尽量使用_b...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CreateThread与_beginthreadex的区别
举报原因:
原因补充:

(最多只允许输入30个字)