CreateThread、_beginthread和_beginthreadex区别

----------------------------------创建线程函数的区别------------------------------------------------------------
CreateThread、_beginthread和_beginthreadex都是用来启动线程的,但大家看到oldworm没有提供_beginthread的方式,
原因简单,_beginthread是_beginthreadex的功能子集,虽然_beginthread内部是调用_beginthreadex但他屏蔽了象安全特性这样的功能,
所以_beginthread与CreateThread不是同等级别,_beginthreadex和CreateThread在功能上完全可替代,我们就来比较一下_beginthreadex与CreateThread.

CRT的函数库在线程出现之前就已经存在,所以原有的CRT不能真正支持线程,这导致我们在编程的时候有了CRT库的选择,在MSDN中查阅CRT的函数时都有:
Libraries
LIBC.LIB Single thread static library, retail version
LIBCMT.LIB Multithread static library, retail version
MSVCRT.LIB Import library for MSVCRT.DLL, retail version
这样的提示!
对于线程的支持是后来的事!
这也导致了许多CRT的函数在多线程的情况下必须有特殊的支持,不能简单的使用CreateThread就OK。
大多的CRT函数都可以在CreateThread线程中使用,看资料说只有signal()函数不可以,会导致进程终止!但可以用并不是说没有问题!

有些CRT的函数象malloc(), fopen(), _open(), strtok(), ctime(), 或localtime()等函数需要专门的线程局部存储的数据块,
这个数据块通常需要在创建线程的时候就建立,如果使用CreateThread,这个数据块就没有建立,然后会怎样呢?
在这样的线程中还是可以使用这些函数而且没有出错,实际上函数发现这个数据块的指针为空时,会自己建立一个,然后将其与线程联系在一起,这意味着如果你用CreateThread来创建线程,然后使用这样的函数,会有一块内存在不知不觉中创建,遗憾的是,
这些函数并不将其删除,而CreateThread和ExitThread也无法知道这件事,于是就会有Memory Leak,在线程频繁启动的软件中(比如某些服务器软件),迟早会让系统的内存资源耗尽!

_beginthreadex(内部也调用CreateThread)和_endthreadex就对这个内存块做了处理,所以没有问题!(不会有人故意用CreateThread创建然后用_endthreadex终止吧,而且线程的终止最好不要显式的调用终止函数,自然退出最好!)

谈到Handle的问题,_beginthread的对应函数_endthread自动的调用了CloseHandle,而_beginthreadex的对应函数_endthreadex则没有,
所以CloseHandle无论如何都是要调用的不过_endthread可以帮你执行自己不必写,其他两种就需要自己写!(Jeffrey Richter强烈推荐尽量不用显式的终止函数,用自然退出的方式,自然退出当然就一定要自己写CloseHandle)

1、不要在一个MFC程序中使用_beginthreadex()或CreateThread()。
这句话的意思是由于AfxBeginThread()是MFC封装的启动线程的函数,里面包含了很多和MFC相关的启动信息,而且封装了一些常用的操作,使用起来也比较简便。而用另外两个函数就需要程序员对类型,安全性检查进行更多的思考!
2、用_beginthreadex()函数应该是最佳选择,因为_beginthreadex()函数是C Run-time Library 中的函数,函数的参数和数据类型都是C Run-time Library中的类型,这样在启动线程时就不需要进行Windows数据类型和C Run-time Library中的数据类型之间的转化。减低了线程启动时的资源消耗和时间的消耗!
3、在C++程序中,几乎都要用到new和delete,难道只有使用_beginthreadex()?
不,因为MFC也是C++类库(只不过是Microsoft的C++类库,不是标准的C++类库),在MFC中也封装了new和delete两中运算符,所以用到new和delete的地方不一定非要使用_beginthreadex() 函数,用其他两个函数都可以!
其实在程序中使用上面的哪个函数并不是绝对的,书的作者只不过是提了一个更佳的搭配方法,我在
MFC程序中也经常使用_beginthreadex()和CreateThread()这两个函数,运行的效果也没有多大的区别,有的时候只是需要你额外的进行一些类型检查和其他的一些转化操作,其余没有其他不妥!
<<windows核心编程>>有详细解释。

### CreateThread _beginthread区别 在 Windows 平台的多线程编程中,`CreateThread` `_beginthread` 是两种创建线程的方式,它们在实现机制、资源管理以及线程安全方面存在显著差异。 `CreateThread` 是 Windows API 提供的一个函数,用于直接创建一个新线程。它允许开发者指定线程的入口函数、参数以及线程的优先级等属性。由于其直接调用操作系统内核的功能,因此提供了较高的灵活性控制能力。然而,这种灵活性也伴随着一定的风险,尤其是在涉及 C 运行时库(CRT)函数时,可能导致线程安全问题[^3]。 相比之下,`_beginthread` 是 Microsoft Visual C++ 运行时库的一部分,它封装了 `CreateThread` 的功能,并在其基础上增加了额外的安全性便利性。`_beginthread` 在内部调用了 `CreateThread`,但在调用前进行了一系列必要的初始化工作,确保了线程能够正确地与 CRT 库集成。例如,在线程退出时,`_beginthread` 会自动释放与线程相关的 CRT 资源,包括线程局部存储(TLS)中的数据[^1]。 ### 使用方法 对于 `CreateThread` 的使用,通常需要定义一个线程入口函数,该函数接受一个 `LPVOID` 类型的参数,并返回一个 `DWORD` 类型的值。接着,调用 `CreateThread` 函数并传入相应的参数来创建线程。以下是一个简单的 `CreateThread` 使用示例: ```c #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParam) { // 线程执行的代码 return 0; } int main() { HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); if (hThread != NULL) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } return 0; } ``` 而对于 `_beginthread`,由于它是 CRT 的一部分,因此更适合那些需要与 CRT 库紧密交互的应用程序。`_beginthread` 接受一个指向线程函数的指针,以及线程函数所需的参数。下面展示了 `_beginthread` 的基本用法: ```c #include <process.h> #include <stdio.h> unsigned int __stdcall ThreadProc(void* lpParam) { // 线程执行的代码 return 0; } int main() { unsigned threadID; HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, NULL, 0, &threadID); if (hThread != NULL) { WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } return 0; } ``` 需要注意的是,`_beginthread` 返回的是一个 `HANDLE` 类型的值,这使得可以通过 `WaitForSingleObject` 来等待线程结束,并通过 `CloseHandle` 来关闭线程句柄[^2]。 ### 总结 综上所述,尽管 `CreateThread` 提供了直接访问操作系统线程创建机制的能力,但在使用 C 运行时库时,推荐使用 `_beginthread` 或者其扩展版本 `_beginthreadex`,因为它们能够更好地处理线程安全问题,并且在线程退出时自动清理 CRT 相关资源。此外,`_beginthread` `_beginthreadex` 还负责分配初始化线程局部存储区域,这对于保证多线程环境下 CRT 函数的正确性至关重要[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值