_beginthreadex 实践小结

本文介绍使用_beginthreadex创建线程及线程与事件结合实现定时执行功能的方法。通过创建事件对象并设置线程执行间隔,利用WaitForSingleObject等待事件超时触发线程执行。

问题1、_beginthreadex创建线程时,返回:0

:参数不对,导致

说明:1参,线程的安全等级,经常使用NULL

2参,线程的堆栈空间大小,如果为0,使用和调用进程相同的空间,经常使用0

3参,线程函数的起始地址,这个是我们线程任务的处理中心

4参,线程函数的参数,与一般的函数参数类似,如果需要传入多个参数,可以使用结构

5参,线程的起始状态,0 == 立即执行, CREATE_SUSPEND == 暂时挂起

6能,线程的ID,线程的标识,至今还没有使用到它的地方

问题2、线程和事件的结合使用

我通常使用事件的有无消息实现线程的定时执行功能,简单步骤如下:

2.1、创建事件对象 HANDLE hMsgEvent = ::CreateEvent(NULL,/*安全属性*/, FALSE/*是否手动重置事件*/, TRUE/*事件的初始信号状态*/, NULL/*事件的名称,一般设置成NULL即可*/); long lTimeInterval = 60000; //线程的执行间隔

2.2、使用_beginThreadEx()创建线程

2.3、在线程函数中,

unsigned _stdcall ThreadProc(void * pArgu)

{

  while(bThreadExit)

  {

    DWORD dwWaitRet = ::WaitForSingleObject(hMsgEvent, lTimeInterval);

    switch(dwWaitRet)

    {

      case WAIT_OBJECT_0:

      //有信号

      break;

      case WAIT_TIMEOUT:

      //超时

      //你要间隔执行的代码

      //......

      break;

      case WAIT_FAILED:

      //出错

      break;

      default:

      break; //常规处理

    }

  }

  return 0;

}

备注:我只是利用超时实现线程的定时触发,你也可以设计多种形式的定时触发机制。

 

 

<think> 我们被要求提供_beginthreadex函数的使用方法。根据引用内容,我们可以总结如下: 1. _beginthreadex函数包含在头文件process.h中(引用[1])。 2. 函数原型为: unsigned long _beginthreadex( void *security, unsigned stack_size, unsigned (__stdcall *start_address)(void *), void *arglist, unsigned initflag, unsigned *thrdaddr ); 3. 该函数用于创建线程,特别当线程中会使用C运行时库(CRT)时,应使用_beginthreadex而不是CreateThread,以避免内存泄漏或其他问题(引用[2][3])。 4. _beginthreadex内部调用了CreateThread,但额外分配了一个tiddata结构与线程关联,用于管理线程特定的数据(如errno),并且需要配合_endthreadex使用(引用[2])。 5. 使用示例(根据引用[4]): ```cpp #include <process.h> #include <Windows.h> unsigned __stdcall ThreadProc(void* lpParameter) { // 线程执行代码 return 0; } int main() { unsigned int thd; HANDLE hThread = (HANDLE)_beginthreadex( NULL, 0, ThreadProc, NULL, 0, &thd ); if (hThread == NULL) { // 处理错误 } // 使用线程句柄... WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0; } ``` 注意: - 线程函数必须使用__stdcall调用约定,且返回值为unsigned int(或unsigned long),参数为void*。 - 创建线程后,应检查返回值(句柄)是否为NULL,以判断是否创建成功。 - 线程结束后,应使用CloseHandle关闭线程句柄(注意:不要在线程函数内关闭自己的句柄,通常在主线程中关闭)。 - 线程函数内部可以使用_endthreadex显式结束线程(但不强制,线程函数返回时会自动调用_endthreadex),但不要使用ExitThread。 另外,根据引用[3],当线程使用CRT时,必须使用_beginthreadex和_endthreadex,否则可能导致内存泄漏或进程终止。 生成相关问题: 1. _beginthreadex和CreateThread的主要区别是什么? 2. 为什么在使用C运行时库的线程中应该使用_beginthreadex? 3. 如何正确结束一个由_beginthreadex创建的线程? </think> ### _beginthreadex 函数使用方法 根据引用内容,`_beginthreadex`是Windows平台创建线程的首选C运行时库函数,尤其当线程需要使用C运行时库(CRT)时。以下是详细使用方法: #### 1. **函数原型**(引用[1][4]) ```cpp unsigned long _beginthreadex( void *security, // 安全属性(通常填NULL) unsigned stack_size, // 初始堆栈大小(0表示默认) unsigned (__stdcall *start_address)(void *), // 线程函数指针 void *arglist, // 传递给线程的参数 unsigned initflag, // 初始状态(0立即运行/CREATE_SUSPENDED挂起) unsigned *thrdaddr // 接收线程ID ); ``` #### 2. **使用步骤** ```cpp #include <process.h> // 必需的头文件(引用[1][4]) // 1. 定义线程函数(必须使用__stdcall调用约定) unsigned __stdcall ThreadProc(void* param) { // 线程执行逻辑 _endthreadex(0); // 推荐显式结束(引用[2]) return 0; } // 2. 创建线程 int main() { unsigned threadID; HANDLE hThread = (HANDLE)_beginthreadex( NULL, // security 0, // stack_size ThreadProc, // 线程函数 nullptr, // 传递给线程的参数 0, // initflag(0=立即运行) &threadID // 接收线程ID ); if (hThread == NULL) { // 错误处理(可通过errno获取错误码) } // 3. 等待线程结束(可选) WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); // 必须关闭句柄 } ``` #### 3. **关键注意事项** 1. **与CreateThread的区别**(引用[2][3]): - `_beginthreadex`内部调用`CreateThread`,但额外分配**tiddata结构**(通过TLS绑定线程) - 解决内存泄漏问题:自动管理线程相关的CRT资源(如`errno`) - 使用CRT时必须用此函数,否则可能导致进程终止(引用[3]) 2. **线程函数要求**: - 必须声明为`unsigned __stdcall`返回类型 - 参数必须是`void*`类型 - 使用`_endthreadex`结束线程(非强制,但推荐) 3. **资源管理**: - 始终检查返回值是否为`NULL` - 使用`CloseHandle`关闭线程句柄(引用[4]) - 避免混合使用`ExitThread`(会导致tiddata泄漏) #### 4. **封装示例**(引用[4]) ```cpp class Thread { public: bool start() { unsigned thd; tid = (HANDLE)_beginthreadex( nullptr, 0, (_beginthreadex_proc_type)execute, this, // 将对象指针作为参数传递 0, &thd ); return tid != NULL; } private: static unsigned __stdcall execute(void* self) { ((Thread*)self)->run(); // 调用成员函数 return 0; } HANDLE tid; }; ``` > **重要提示**:当线程涉及文件操作、内存分配或使用`errno`等CRT功能时,**必须使用`_beginthreadex`而非`CreateThread`**,否则可能引发内存泄漏或运行时错误(引用[2][3])。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值