书籍:《Visual C++ 2017从入门到精通》
环境:Visual Studio 2022
内容:[例8.16]利用_beginthread不断创建线程
1. 函数来源与用途
_beginthread() 和 _endthread() 是 C运行时库(CRT) 提供的线程管理函数,主要用于简化线程的创建和终止过程。_beginthread():创建并启动一个新线程,自动初始化与C运行时库相关的资源(如线程局部存储)。_endthread():终止当前线程,并释放相关资源。
2. 函数原型与参数
2.1 _beginthread()
uintptr_t _beginthread(
void( *start_address )( void * ), // 线程入口函数
unsigned stack_size, // 线程栈大小(默认为1MB)
void *arglist // 传递给线程函数的参数
);
返回值:线程句柄(HANDLE),失败时返回 -1。特点:
自动分配线程栈空间(若 stack_size 为0)。初始化C运行时库的线程数据(如 errno、文件流等)。必须与 _endthread() 配合使用。
2.2 _endthread()
void _endthread( void );
作用:终止当前线程,释放资源。调用方式:通常在线程函数末尾隐式调用,也可显式调用。
3. 工作流程
3.1 使用 _beginthread() 创建线程
#include
unsigned __stdcall ThreadFunc(void* param) {
// 线程逻辑
_endthread(); // 显式终止线程(可选)
return 0;
}
int main() {
uintptr_t hThread = _beginthread(ThreadFunc, 0, NULL);
if (hThread == -1) {
// 错误处理
}
WaitForSingleObject((HANDLE)hThread, INFINITE); // 等待线程结束
CloseHandle((HANDLE)hThread);
return 0;
}
3.2 线程终止
隐式终止:线程函数执行完毕时,自动调用 _endthread()。显式终止:在任意位置调用 _endthread(),但需确保资源已释放。
4. 与 CreateThread 的区别
特性_beginthread()CreateThread所属库C运行时库(CRT)Windows API栈初始化自动分配和初始化栈需手动指定栈大小运行时库兼容性初始化CRT数据(如 errno)不初始化CRT数据线程局部存储(TLS)自动分配需手动处理异常处理支持C++异常需通过结构化异常处理(SEH)
5. 关键注意事项
5.1 必须配对使用
若使用 _beginthread() 创建线程,必须在线程函数中调用 _endthread(),否则可能导致资源泄漏(如未释放的文件句柄)。
5.2 栈大小管理
默认栈大小为1MB,可通过 stack_size 参数调整。过小的栈可能导致栈溢出,过大会浪费内存。
5.3 线程函数签名
线程函数必须符合 void (*)(void*) 格式,返回类型为 unsigned __stdcall。
5.4 与C++的兼容性
_beginthread() 不支持C++异常,若需使用C++异常,应改用 _beginthreadex()(Windows API扩展)。
6. 示例代码:多线程求和
#include
#include
unsigned __stdcall SumThread(void* param) {
int* data = (int*)param;
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += data[i];
}
printf("Sum: %d
", sum);
_endthread();
return 0;
}
int main() {
int data[100];
for (int i = 0; i < 100; i++) {
data[i] = i + 1;
}
uintptr_t hThread = _beginthread(SumThread, 0, data);
if (hThread == -1) {
printf("Failed to create thread.
");
return 1;
}
WaitForSingleObject((HANDLE)hThread, INFINITE);
CloseHandle((HANDLE)hThread);
return 0;
}
7. 替代方案与现代实践
推荐使用 std::thread:C++11及以上版本提供了跨平台的线程库,无需依赖CRT。使用 _beginthreadex():若需更精细的控制(如返回线程ID),可使用Windows API的 _beginthreadex()。
8. 总结
_beginthread() 和 _endthread() 是CRT提供的简化线程管理工具,适合快速开发小型多线程程序。优点:自动初始化CRT资源,简化线程创建。缺点:功能有限,不适合复杂场景(如C++异常、跨平台开发)。适用场景:Windows平台下的简单多线程任务,或与C标准库深度集成的项目。
实际开发中,建议优先使用C++11的 std::thread 或Windows API的 CreateThread,以获得更好的灵活性和可维护性。