MFC thread _beginthreadex CreateThread AfxBeginThread 对比
CreateThread
CreateThread函数是Windows的一个API函数
操作系统级别的创建线程的操作,且仅限于工作者线程。不调用MFC和RTL的函数时,可以用CreateThread,其它情况不要轻易用。
_beginthreadex
_beginthreadex函数是C/C++运行库提供的函数,
C/C++运行库的意思是 编译器 封装的函数,符合C/C++标准,底层调用了CreateThread函数
MS对C Runtime库的扩展SDK函数,首先针对C Runtime库做了一些初始化的工作,以保证C Runtime库工作正常。然后,调用CreateThread真正创建线程。
AfxBeginThread
MFC中线程创建的MFC函数
MFC中线程创建的MFC函数,首先创建了相应的CWinThread对象,然后调用CWinThread::CreateThread, 在CWinThread::CreateThread中,完成了对线程对象的初始化工作,然后,调用_beginthreadex(AfxBeginThread相比较更为安全)创建线程。
CreateThread是一个Windows 的API函数,
_beginthreadex是一个微软VC中C运行时库中的线程创建函数,
AfxBeginThread则是MFC中的线程创建函数。
1
_beginthreadex为每个使用线程在Heap上创建(用__calloc_crt,相当于calloc)了一个tiddata结构并且设定到动态TLS。这样C运行时库中使用静态变量的几个函数就可以得到只和线程相关的一份“静态”和“全局”变量了,C运行时全局变量也不会互相干扰。假若使用CreateThread创建了这同样的线程,因为没有事先分配这个tiddata结构,那么后果自然就很严重了。
但是使用了_beginthreadex也有一个不算麻烦的小麻烦。
线程最好的退出方式是从return退出,所有的资源都会正确的释放,如果调用ExitThread退出线程,那么线程堆栈上的内容被自动清除,但是C++对象不能够通过调用析构函数而正确的清除。而和_beginthreadex对应的_endthreadex恰恰就是调用了ExitThread来终止线程。所以,这下_endthreadex也不能调用了。那么在前面分配的tiddata怎么办?没有任何办法,除非去调用_endthreadex才会得到释放,但是ExitThread语句又紧跟在后边。还好,tiddata结构非常小,不超过100个字节,但是要是遇上傻大黑粗的野蛮程序员,在进程生命期中反复创建线程,也挺恐怖。
所以最好的做法就是,在线程中,避免使用C运行时函数,用C++运行时库或者Windows API解决问题。这样就可以避免使用_beginthreadex,而用CreateThread创建线程,也不会有tiddata结构的运行时内存泄漏了。(或者,不在线程中使用C++对象,这样就不怕_endthreadex的ExitThread 了。 吐舌 馊主意!不过_beginthreadex本来就是为使用C函数的线程准备的。)
至于AfxBeginThread,是MFC中定义的一个函数,如果你使用MFC框架,那么应该使用这个函数,这样更符合框架的设计目的。这个函数内部的实现就是通过CreateThread,因为既然都使用MFC了,还费劲使用C函数库干嘛?
上面 这一段话是从网上复制的
_beginthreadex 是 属于C++运行时库 ,不属于 C运行时函数
线程中 C运行时函数 应该被避免使用
C运行时函数 包括哪些呢?
因此,Visual C++提供了两种版本的C运行时库。一个版本供单线程应用程序调用,另一个版本供多线程应用程序调用。多线程运行时库与单线程运行时库有两个重大差别:
(1)类似errno的全局变量,每个线程单独设置一个;
这样从每个线程中可以获取正确的错误信息。
(2)多线程库中的数据结构以同步机制加以保护。
这样可以避免访问时候的冲突。
MSDN上的警告
不要混合使用运行时库的静态版本和动态版本。在一个进程中有多个运行时库副本会导致问题,因为副本中的静态数据不与其他副本共享。链接器禁止在 .exe 文件内部既使用静态版本又使用动态版本链接,但您仍可以使用运行时库的两个(或更多)副本。例如,当与用动态 (DLL) 版本的运行时库链接的 .exe 文件一起使用时,用静态(非 DLL)版本的运行时库链接的动态链接库可能导致问题。(还应该避免在一个进程中混合使用这些库的调试版本和非调试版本)。
四、举例
C运行时库除了给我们提供必要的库函数调用(如memcpy、printf、malloc等)之外,它提供的另一个最重要的功能是为应用程序添加启动函数。
MFC thread _beginthreadex CreateThread AfxBeginThread 对比相关推荐
- CreateThread、_beginthreadex、AfxBeginThread
1.CreateThread._beginthreadex.AfxBeginThread的区别和正确使用: CreateThread是一个Windows的API函数,_beginthreadex是一个 ...
- CreateThread、_beginthreadex和AfxBeginThread 的区别
CreateThread._beginthreadex和AfxBeginThread 创建线程好几个函数可以使用,可是它们有什么区别,适用于什么情况呢? 参考了一些资料,写得都挺好的,这里做一些摘抄和 ...
- ATL与MFC消息分发机制的对比---由金山开源代码引出的思考(一)
博客已迁移至:http://kulv.sinaapp.com/,这里不再使用 ATL与MFC消息分发机制的对比---由金山开源代码引出的思考 (一) 前几天刚看金山开源代码时写了一篇博客分析了一下其消 ...
- mfc 创建线程函数AfxBeginThread,线程中访问mfc控件
转字http://blog.csdn.net/guomsh/article/details/10377993 1. C++ 中如何定义线程函数 有两种方法:a. 定义线程函数为全局函数 b. 定 ...
- std::thread vs CreateThread
从 C++11 开始,线程,成为了 C++ 标准库的一部分,所以我们可以不再使用 CreateThread 来创建线程,简简单单地使用 std::thread 即可. 而且,CreateThread ...
- 《编码checklist规范》学习笔记
<编码checklist规范>学习笔记 <编码checklist规范>posts <编码checklist规范>学习笔记 0 前言 1 排版 1.0 总则 1.1 ...
- CreateThread()函数及_beginthreadex()函数
CreateThread():创建一个线程可以调用进程的虚拟地址空间内执行.创建的线程终止运行后,线程对象仍然在系统中,必须通过CloseHandle函数来关闭该线程对象. 函数原型: HANDLE ...
- MFC的进程和线程,非正常终止
进程是一个可执行的程序,由私有虚拟地址空间.代码.数据和其他操作系统资源(如进程创建的文件.管道.同步对象等)组成.一个应用程序可以有一个或多个进程,一个进程可以有一个或多个线程,其中一个是主线程. ...
- c语言第一个mfc程序,c语言之MFC的进程和线程
MFC的进程和线程 1.Win32的进程和线程概念 进程是:一个可执行的程序,由私有虚拟地址空间.代码.数据和其他操作系统资源(如进程创建的文件.管道.同步对象等)组成.一个应用程序可以有一个或多个进 ...
最新文章
- Linux 关于动态链接库以及静态链接库的一些概念
- pid控制器c51语言编程,51单片机电机pid控制系统程序
- python requests用法总结
- 上传docker镜像到hub.docker
- while循环random结合_Python程序控制结构 | 循环结构
- c++删除文件delete_关于macos删除快捷键,你知道这些区别用法吗?
- 【动手学深度学习】代码(持续更新)
- [Matlab]绘图颜色
- 日常提醒(delphi源码)
- upnp 文件服务器,upnp服务器
- GNU GRUBversion 2.04Minimal BASH-like line editing is supported.For the first word
- 项目管理高手常用的10种图表!
- 【Redis学习05】优惠券秒杀及其优化
- Servlet 原理
- GLES2.0中文API-glGetActiveUniform
- 20220528【聊聊假芯片】贪便宜往往吃大亏,盘点下那些假的内存卡和固态硬盘
- 不看不知道 轿车制造成本大揭密
- 想精通 Python 数据挖掘?清华博士带你入门!
- eureka注册中心wro.css wro.js 404
- web前端入门到实战:css绘制各种形状图形