为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行,这种行为叫进程切换(process switch),任务切换(task switch)或上下文切换(context switch)。个人习惯将之称为context switch,因为context这个单词能够比较准确的形容进程运行的环境。

 

一,进程在内核态的context

每一个进程都有它自己的内核态上下文。Linux把两个不同的数据结构紧凑的存放在一个单独为进程分配的存储区域内:一个是与进程描述符相关的小数据结构thread_info,叫作线程描述符,另一个是内核态的进程堆栈。这块存储区域通常有8K。这块区域的地址存放在进程描述符task_struct中。参考:http://www.cnblogs.com/hxdoit/p/3619430.html

从效率的观点来看,为什么把thread_info结构和内核态堆栈放在一起的好处是:内核很容易从esp寄存器中获取当前thread_info结构体的位置,这就少了几次指针操作。

当前进程中,esp指针指向上图中的0x015fbfff,当栈里面的数据从顶端向下增长时,esp的值就会递减。

thread_info结构和进程内核态栈放在一起称为thread_union结构体。

因为thread_union的地址是8K对齐的,所以将esp的值砍掉低13位就可以thread_info的地址。

二,硬中断和软中断context

不多说了,直接截图,如下。结论就是,内核可以直接使用进程的内核态栈来处理(软/硬)中断,也可以使用专用的内核栈。