linux进程切换,进程上下文,thread_union数据结构(task_union V0.11)

进程是操作系统中很重要的一个抽象,是对程序的一次执行实例的抽象。每个进程运行在自己的上下中,其上下文包括被进程正文所定义的进程状态、进程的全局用户变量和数据结构、它使用的寄存器的值、存储在它的进程表项的值以及它的用户栈和核心栈的内容。当出现执行中进程发生中断或异常内核会执行中断或异常处理函数,此时若进程运行在用户态下,会发生执行态切换,但内核并不产生或调度其他进程来处理中断或异常。

进程切换会发生在以下两种情况下:

1)进程因为等待某资源,调用sleep_on()进入睡眠状态,自愿放弃CPU的使用权,内核执行schedule()进行调度。

2)当前进程所分配的时间片运行完,并且此时有更高优先级的进程处于就绪状态,则内核执行schedule(),执行进程抢占。

从本质上说,每个进程切换由两步组成:

1)切换页全局目录以安装一个新的地址空间,只需要更新cr3页目录基址寄存器即可。

2)切换内核态堆栈和上下文信息。

在Linux中,Linux为每个处理器而不是为每个进程使用TSS,所以进程被切换出去,内核就把其上下文保存在thread_struct的thread字段。这个数据结构包括的字段涉及大部分CPU寄存器,但不包括诸如eax、ebx等通用寄存器,它们被保留在内核态堆栈中。因为所有进程的ss0都是统一的,为内核的ss,内核在初始化的时候,已经将该Tss0设置为自己的ss,因此无需继续设置ss0,把换入进程的esp0装入CPU的TSS的esp0字段。

说到内核态堆栈,这也是一个很重要的数据结构。定义如下:

union thread_union{

   struct thread_info thread_info;  //52byte

   unsigned long stack[2048];  //8K

};

用上面的联合结构方便的表示一个进程的线程描述符和内核栈,可用下图表示:


实现了在2页(8K)内存区中存放两种数据结构的方式。由于通常进程内核态堆栈不像用户态堆栈那样大,所以不会出现堆栈由于压入数据太多把thread_info的数据覆盖的情况。内核从esp寄存器的值可以获得当前在CPU上运行进程的thread_info结构的地址。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值