详细分析 _beginthread() 和 _endthread()

书籍:《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 <process.h>

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 <process.h>
#include <stdio.h>

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,以获得更好的灵活性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值