20170618Windows10_04_线程从启动到消亡、创建线程

线程:

线程从启动到消亡过程详细讲解:

1:从CreateThread开始,会创建一个线程内核对象(是一个结构体),线程内核对象里面有:
        使用计数(CreateThread后为2),用于记录。
        暂停计数,暂停计数为UINT类型,为0才可以运行,在刚初始化线程内核对象后,其值为1。
        退出代码(STILL_ACTIVE):
        Signaled(FALSE):
2:创建内核对象后会分配一块栈空间,会在前面的位置压入一些参数:lpParam、lpfnAddr。
3:每个线程都有一个线程上下文的结构体(CONTEXT),在WinNT.h里面:
        线程上下文里面保存了上一次运行的寄存器状态。特别关心的是EIP和ESP寄存器的值,EIP为指令寄存器,指向下一条代码在哪里(RtlUserThreadStart),ESP为栈寄存器,指向栈顶(lpfnAddr)。RtlUserThreadStart这个函数是不可以调用的,他是一个未导出函数,但是其是存在的,接收两个参数:lpParam和lpfnAddr,返回值为void。线程切换的时候,完全是靠线程上下文来做的。每次切换就会将状态加载到CPU。
4:交给CPU调度,运行。
5:最后,RtlUserThreadStart会设置一个结构化异常(SEH),可以让操作系统处理这些异常情况,然后会调用线程函数,并且将lpParam参数传递进去,他会等待线程函数的返回,线程返回之后,会在内部调用ExitThread,并且将线程函数的返回值传递给ExitThread,然后线程内核对象的使用计数就会减少,线程消亡。

_beginthreadex和CreateThread

1:errno是C语言的错误处理方法,但是其是非线程安全的,他们本身是通过全局变量来做的。_beginthreadex里面传递的参数意义与CreateThread是一样的但是意义有区别,前者是C语言的,里面的变量类型都是C语言标准的,后者是C++的,参数类型使用了Windows的一些变量类型。
2:_beginthreadex会多分配一块空间来保存errno这一类全局变量,他不会被其他线程更改,来确保线程安全。然后会调用CreateThread来创建线程。左后需要调用_endthread来释放,他会将多分配的那一块控件释放掉。
3:以后创建线程最好使用_beginthreadex,而不实用CreateThread,他会相对更加安全。_beginthread也不会多分配这一块空间,与_beginthreadex是有区别的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值