Windows Via C/C++:线程实现细节
来源:互联网 发布:宝马电脑编程 编辑:程序博客网 时间:2024/04/29 15:55
我们已经了解如何定义线程入口点函数、调用系统API创建执行指定函数的线程。本节将揭示这一切在系统内部是如何完成的。
图6-1描述了线程创建并完成初始化后的状态。调用CreateThread会使系统产生一个线程内核对象,其引用计数(Usage count)被初始化为2(创建线程的进程和线程本身都引用了该内核对象),其它属性也完成了初始化:暂停计数(Suspend count)被设置为1,线程退出码(Exit code)被设置为STILL_ACTIVE,内核对象状态被置为nonsignaled(Signaled)。
内核对象创建完成后,系统在当前进程中为新线程的线程栈分配内存,并在线程栈的高位写入两个值。第1个指是CreateThread函数的pvParam参数,然后是pfnStartAddr参数。
每个线程有自己的CPU寄存器组,被称为线程上下文(Context),线程的上下文反映了线程最后一次执行时其CPU寄存器的状态。WinNT.h中定义了CONTEXT结构对应线程的CPU寄存器组,线程的CONTEXT实例保存在其内核对象中。
线程上下文中最重要的两个寄存器是指令指针寄存器(Instruction pointer)和栈指针寄存器(Stack pointer)。由于线程是运行在进程地址空间内的,因此其栈中的地址就是进程地址空间中的地址。线程内核对象初始化时,其CONTEXT结构中的栈指针寄存器内容被设置为pfnStartAddr在线程栈中的地址,指令指针寄存器内容被设置为名为RtlUserThreadStart的函数的地址,该函数在NTDLL.dll中定义,基本框架如下所示:
VOID RtlUserThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam) { __try { ExitThread((pfnStartAddr)(pvParam)); } __except(UnhandledExceptionFilter(GetExceptionInformation())) { ExitProcess(GetExceptionCode()); } // NOTE: We never get here.}
线程初始化完成后,系统会检查CreateThread是否传递了CREATE_SUSPENDED参数,如果没有的话,系统会把线程内核对象的暂停计数设置为0并马上调度线程,然后将线程上下文中的值加载到CPU的寄存器组中,由于线程指令指针寄存器指向RtlUserThreadStart,因此线程将以RtlUserThreadStart开始执行,RtlUserThreadStart又调用了CreateThread为线程设置的入口点函数pfnStartAddr,并在pfnStartAddr返回时调用ExitThread退出线程。要注意假如在pfnStartAddr执行时发生了未处理的异常,RtlUserThreadStart中的结构化异常处理框架将执行ExitProcess,导致整个进程的退出。
- Windows Via C/C++:线程实现细节
- Windows Via C/C++:线程概述
- Windows via C/C++:线程的执行时间
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- 《windows via C++》之windows线程同步
- 《Windows via C/C++》学习笔记 —— Windows 线程
- Windows Via C/C++:线程入口点函数
- Windows via C/C++:线程调度——概述
- Windows Via C/C++:线程的挂起和恢复
- Windows Via C/C++:线程的睡眠和切换
- 《Windows via C/C++》学习笔记(二线程)
- 《Windows via C/C++》学习笔记(三)线程
- Windows via C/C++:线程的执行时间(1)
- windows via c/c++
- Windows via c/c++
- Windows Via C/C++
- Windows Via C/C++ 读书笔记 4 线程调度 优先级
- 精妙sql语句
- 解SQL加密存储过程
- 自动备份
- ListView 写入到指定行列Demo
- 跨服务器操作
- Windows Via C/C++:线程实现细节
- Transact-SQL语句总汇
- Java的特性-assertion
- 闲来无事之自动换桌面墙纸--WallpaperAutoChanger
- 查数据库中的表,了解大体结构
- ubuntu-禁掉在终端提示出错的小喇叭嘀嘀声
- 管理过程组与PDCA循环的关系
- Ria Service DomainDataSource + datagrid 的新增数据问题
- 理解虚基类、虚函数与纯虚函数的概念