【多线程简单实例】_beginthreadx实现

使用_beginthreadex()函数,需使用头文件<processs.h>,且进行编译环境的设置(详见上篇文章)。

线程的创建和终止

C++代码:

#include<iostream>
#include<windows.h>
#include<process.h>
using namespace std;

static unsigned _stdcall Thread1(void *param);
static unsigned _stdcall Thread2(void *param);

int main()
{
    //创建第一个线程
    HANDLE T1;
    unsigned  T1_ID;
    T1= (HANDLE)_beginthreadex( NULL,        
                                   0,          
                                   Thread1,
                                   NULL,          
                                   CREATE_SUSPENDED,  
                                   &T1_ID );

    if ( T1 == 0 )       cout<<"Failed to create Thread1..."<<endl;
    DWORD   T1Code;
    GetExitCodeThread(T1, &T1Code );  // should be STILL_ACTIVE = 0x00000103 = 259
    cout<<"Initial Thread1 Exit Code is "<<T1Code<<endl;

    //创建第二个线程
    HANDLE T2;
    unsigned T2_ID;
    T2=(HANDLE)_beginthreadex(
                                NULL,
                                0,
                                Thread2,
                                NULL,
                                CREATE_SUSPENDED,
                                &T2_ID);
    if(T2==0)   cout<<"Failed to create Thread2..."<<endl;
    DWORD T2CODE;
    GetExitCodeThread(T2,&T2CODE);
    cout<<"Initial Thread2 Exit Code is "<<T2CODE<<endl;

    ResumeThread( T1 );   
    ResumeThread( T2 );   

    WaitForSingleObject( T1, INFINITE );
    WaitForSingleObject( T2, INFINITE );

    CloseHandle( T1 );
    CloseHandle( T2 );
    return 0;
}

static unsigned _stdcall Thread1(void *param)
    {
        cout<<"The Thread1 IS WORKING..."<<endl;
        Sleep(500);
        return 1;
    }
static unsigned _stdcall Thread2(void *param)
{
    Sleep(500);
    cout<<"The Thread2 IS WORKING..."<<endl;
    return 1;
}

代码详解

与CreateThread()相同的部分不再赘述

  • _beginthreadex()函数,比_beginthread()更安全一些.因为beginthread隐式调用了CloseHandle关闭了线程句柄,而与_beginthreadex成对使用的_endthreadex则没有关闭线程的句柄,需要显示调用CloseHandle来关闭线程句柄,从逻辑上更安全。
    _beginthreadex()函数原型:
_beginthreadex(
void *secAttr, 
unsigned stackSize,
unsigned (__stdcall *threadFunc)(void *),
void *param, 
unsigned flags,
unsigned *threadID);

_beginthreadex()的参数类似于CreateThread()的参数,且与CreateThread()指定的参数有相同的含义。
函数说明:
1. 第一个参数secAttr是描述线程内核对象安全属性的指针,设置为NULL,就会使用默认的安全描述符。
2. 第二个参数stackSize表示线程栈空间大小。如果为0(1MB),那么这个线程堆栈的大小与创建它的线程相同。
3. threadFunc表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址,线程的执行一直持续到线程函数返回。 这个函数的地址在下面的函数中指定。每个线程函数都必须具有这样的原型。线程函数的地址(也就是线程的入口点)在Thread中指定。对于_beginthreadex(),线程函数的原型如下:
static unsigned_stdcall Thread(void *param)
这个原型在功能上等价于CreateThread()的线程函数的原型,但是它使用了不同的类型名称。
stdcall的调用约定意味着:
1)参数从右向左压入堆栈;
2)函数自身修改堆栈;
3)函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸。。
4.第四个参数param是传给线程函数的参数。
5.第五个参数flags标志了线程的执行状态,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED,线程则以挂起状态创建并等待执行,这样它就无法调度,直到调用ResumeThread()。
6.第六个参数threadid将以的长整型返回线程的ID号,传入NULL表示不需要返回该线程ID号。

  • ResumeThread( ); 线程恢复函数。
    函数原型:DWORD WINAPI ResumeThread( __in HANDLE hThread);
    HANDLE hThread你需要恢复线程的句柄使用该函数能够激活线程的运行,使CPU分配资源让线程恢复运行。
  • GetExitCodeThread();用于获取一个已中止线程的退出代码。
 BOOL  GetExitCodeThread (
       HANDLE         hThread,                  
       LPDWORD      lpExitCode               
);

hThread Long,想获取退出代码的一个线程的句柄
lpExitCode Long,用于装载线程退出代码的一个长整数变量。如线程尚未中断,则设为常数STILL_ACTIVE。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值