首页 理论教育 操作系统实现之路:理解线程的上下文

操作系统实现之路:理解线程的上下文

时间:2023-10-21 理论教育 版权反馈
【摘要】:表4-5 核心线程各寄存器的初始化值按照IA32的体系结构,EFLAGS寄存器的内容如图4-3所示。目前Hello China的实现没有引入进程的概念,整个操作系统只有一个地址空间,所有核心线程共享这个地址空间,因此,所有线程对应的CS寄存器值相同,都为8。而对于EIP寄存器的值,设置为线程起始函数的地址。图4-4显示了线程起始函数和线程功能函数之间的关系。图4-4 核心线程的生命周期

操作系统实现之路:理解线程的上下文

线程上下文(Context)是一个类型为__KERNEL_THREAD_CONTEXT的结构体,该结构体与特定的硬件平台(CPU)有强关联关系,不同的硬件平台,该结构体的定义不同。本书重点关注Intel IA32构架的CPU。在这种硬件平台下,该结构体的定义如下(为了解释简便,删除了部分注释):

978-7-111-41444-5-Chapter04-18.jpg

表4-5给出了对应的IA32硬件平台的硬件寄存器与上述结构中成员的对应关系。

表4-5 核心线程各寄存器的初始化

978-7-111-41444-5-Chapter04-19.jpg

按照IA32的体系结构,EFLAGS寄存器的内容如图4-3所示。

978-7-111-41444-5-Chapter04-20.jpg

图4-3 EFLAGS寄存器各比特的含义

每个核心线程初始化的时候,我们把EFLAGS(dwEflags)寄存器的值设置为512,也就是在上述寄存器标志位中,只把IF(中断允许标志)设置为1,这样允许中断。所有其他标志均设置为0。(www.xing528.com)

目前Hello China的实现没有引入进程的概念,整个操作系统只有一个地址空间,所有核心线程共享这个地址空间,因此,所有线程对应的CS寄存器值相同,都为8(代码段在GDT中的索引值)。针对每个线程,操作系统都创建一个堆栈,该堆栈实际上是一块物理内存,在初始化的时候,堆栈寄存器ESP指向了该物理内存的末端(不是首地址,因为堆栈是按照从上往下的方向增长的,但也不是严格的末地址,而是在末地址的基础上,再减去8,详细信息可参考4.2.5节)。

而对于EIP寄存器的值,设置为线程起始函数的地址。需要注意的是,这个起始函数并不是线程工作函数,线程工作函数被线程起始函数调用,来完成具体的工作,而在调用线程工作函数之前,线程起始函数还需要做一些其他的工作,比如初始化核心线程对象等。下面是Hello China实现的线程起始函数的部分代码:

978-7-111-41444-5-Chapter04-21.jpg

978-7-111-41444-5-Chapter04-22.jpg

上述代码中的黑体部分实际上是调用了线程的功能函数(以用户提供的参数为参数,在应用程序调用CreateKernelThread的时候,CreateKernelThread创建一个核心线程对象,并把用户提供的线程功能函数和参数存储到该对象中,详细信息请参考4.2.5节)。需要注意的是,在从功能函数调用返回后,线程起始函数并没有马上返回,而是做了一些收尾处理,比如设置线程的返回值,设置线程核心对象的状态(设置为TERMINAL),唤醒等待该线程的其他核心线程等。

从上述代码中还可用看出,应用程序可以创建一个没有任何功能函数的“空线程”,因为在调用线程的功能函数前,线程起始函数先做了检查,若功能函数为空,则直接跳转到末尾,否则再调用功能函数。图4-4显示了线程起始函数和线程功能函数之间的关系。

978-7-111-41444-5-Chapter04-23.jpg

图4-4 核心线程的生命周期

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈