Windows线程启动和消亡详解
来源:互联网 发布:淘宝退货申请假冒品牌 编辑:程序博客网 时间:2024/06/03 13:39
线程的创建:前提条件,线程的创建是在某一个进程当中调用CreateThread()创建一个线程。
线程的创建:
No.1:创建内核对象。
1.使用计数:设置使用计数+1,当一个线程被创建的时候,线程内核的使用计数会加1.
2.暂停计数:设置暂停计数,这个参数是一个UINT 类型的,这就代表着这个线程可以被多次的暂停。当一个线程被创建出来的时候,暂停计数是1的状态,只有当暂停计数为0的时 线程才会启动。
3.退出代码:线程初始化启动时候线程的退出代码会被设置成STILL_ACTIVE。
4.信号(Signaled):线程的信号会被设置成False。
5.CONTEXT:在线程刚被创建的时候就会创建一个线程的上下文的结构体,但是在这里它还没有被初始化。
No.2:设置栈
线程创建到这一步的时候,会去线程所在的进程内申请一块空间,给我们的栈使用。然后lpParam(线程传递参数)和 lpfnAddr(线程入口函数)这两个参数会被压入线程入口处去的前两个栈中。
No.3:CONTEXT:
在有了栈空间的情况下, 接下来就会初始化我们的CONTEXT,CONTEXT是保存了线程在上一次运行时CPU寄存器的状态。
这里重点说明一下EIP和ESP寄存器在的状态。
EIP(指令寄存器):会调用Void RtlUserThreadStart(lpParam,lpfnAddr)这个函数,这个函数是个未公开的函数。这个函数分别接受这两个参数。
ESP(栈寄存器):ESP会指向lpfnAddr。也就是栈顶的位置。
这里要说明下线程的切换->线程的切换其实就是在切换问题。线程的切换其实就是在切换CONTEXT线程的上下文。当CONTEXT被切换的时候,会先将CONTEXT里面的内容加载物理寄存器当中,物理寄存器会根据EIP指令寄存器来进行代码的执行。
NO.4:CPU调用
当CONTEXT也被初始化了之后,这里就进入到了CPU的调用阶段。调用之前,会检查线程是否被设置成暂停状态,如果线程没有被设置成暂停状态,那么,就会将线程的暂停计数-1,然后执行线程。
消亡:
No.5:调用RtlUserThreadStart
1.创建一个管理异常的结构体SEH。
2.调用线程函数,CreateThread是在RtlUserThreadStart中被调用的,并且将lpParam这个参数传递进去。
3.等待线程函数的返回值。
4.调用ExitThread,这个时候,线程的内核使用计数就会递减。
小结:由上面的叙述可知,线程的启动和消亡的整个过程中,RtlUserThreadStart,和CONTEXT这两个东西起到了很重要的作用。整个线程的调用和消亡来自RtlUserThreadStart,线程的运行代码和当前运行状态都保存在CONTEXT当中。
- Windows线程启动和消亡详解
- Windows线程启动到消亡的运行状态
- 20170618Windows10_04_线程从启动到消亡、创建线程
- PDM 的诞生和消亡
- 进程的诞生和消亡
- 已消亡和正在消亡的10项计算机技术
- 已消亡和正在消亡的10项计算机技术
- Java 线程的创建与消亡
- Java 线程的创建与消亡
- Windows启动过程详解
- Windows启动过程详解
- Windows启动过程详解
- Windows启动过程详解
- Windows启动过程详解
- Windows启动过程详解
- windows启动过程详解
- Windows启动过程详解
- Windows启动详解
- 无人机系统PX4视频教程:飞行PID参数调试
- 菜鸟日记(yzy) 微信公众号网页的开发-websocket
- 生成HFile以及入库到HBase
- windows任务计划
- centos7中yum安装软件问题
- Windows线程启动和消亡详解
- Storm Trident API 使用详解
- java io File API的使用
- NodeJS常用模块介绍
- JS中的数组去重方法总结
- bootstrapTable ie刷新无效
- AliExpress:在检索式问答系统中应用迁移学习 | PaperDaily #24
- 直接插入排序验证性实验
- 进制转换