linux 进程切换执行流的分离

来源:互联网 发布:windows 8 whql 编辑:程序博客网 时间:2024/04/28 05:09

所谓进程的切换,实际上就是属于进程上下文的寄存器和堆栈的切换,以及页表的切换。切换总是发生在内核态。对于一个执行流来说,它本身是感知不到所谓进程切换的,它只是机械的按照代码执行,取ip的执行地址,执行完毕后进行自加。

进程切换一般不会显式的设置eip/rip寄存器的值。设置ip寄存器值一般是需要jmp的时候。那么进程切换后执行路径的不同不是通过设置ip来实现的,那么是怎么实现的?

可能有人认为x86 64上进程切换前后会保存切换前的执行地址到堆栈,然后下次切换回来的时候再恢复,这么说是不确切的。实际上发生切换的前后,内核没有显式保存ip地址。

之所以切换进程后,执行路径不同,是因为发生了栈切换。具体说,内核栈切换之后,栈里面存储的函数返回地址不同,因此一但切换后再执行ret函数返回,这时候因为从栈里面弹出的返回地址不同所以执行路径就分开了。

实际上内核完成switch_to的这部分代码不是函数,是一个宏,因为只有函数才有把返回地址压栈的动作,所以实际上switch_to执行后,切换前后的进程会继续都沿着后面一个相同的路径继续执行下去,直到遇到ret指令!但是switch_to中切换堆栈和寄存器后,实际上进程切换已经完成,只不过2个进程这时候执行流还没有分开,需要继续执行一段相同的代码直到遇见ret。

由于编译器优化的原因,因此很多函数会被优化为内联,这时候就会发现switch_to切换后新进程又继续执行了切换前进程的一部分,直到遇到真正ret才会返回新进程执行流。

0 0
原创粉丝点击