简述进程和线程的主要区别 进程线程区别( 三 )


附:我们通常所说的上下文切换具体指什么?
操作系统抽象出一个进程的概念 , 让应用程序专心于实现自己的业务逻辑既可 , 对应用程序屏蔽了CPU调度、内存管理等硬件细节 , 而且在有限的CPU上可以“同时”进行许多个任务 。但是它为用户带来方便的同时 , 也引入了一些额外的开销 。
在操作系统中 , 由于CPU的时间片调度策略 , 从一个进程切换到另一个进程需要保存当前进程的状态并恢复另一个进程的状态:当前运行任务转为就绪(或者挂起、删除)状态 , 另一个被选定的就绪任务成为当前任务 。上下文切换包括保存当前任务的运行环境 , 恢复将要运行任务的运行环境 。
在上下文切换过程中 , CPU会停止处理当前运行的程序 , 并保存当前程序运行的具体位置以便之后继续运行 。从这个角度来看 , 上下文切换有点像我们同时阅读几本书 , 在来回切换书本的同时我们需要记住每本书当前读到的页码 。
在三种情况下可能会发生上下文切换:中断处理 , 多任务处理 , 内核/用户态切换 。
在中断处理中 , 其他程序”打断”了当前正在运行的程序 。当CPU接收到中断请求时 , 会在正在运行的程序和发起中断请求的程序之间进行一次上下文切换 。
在多任务处理中 , CPU会在不同程序之间来回切换 , 每个程序都有相应的处理时间片 , CPU在两个时间片的间隔中进行上下文切换 。
在Linux中进行内核/用户态切换也会进行上下文切换 , 进行系统调用时 , CPU寄存器里原来用户态的指令位置需要先保存起来 。接着 , 为了执行内核态代码 , CPU寄存器需要更新为内核态指令的新位置 。最后才是跳转到内核态运行内核任务 。而系统调用结束后 , CPU寄存器需要恢复原来保存的用户态 , 然后再切换到用户空间 , 继续运行进程 , 所以一次系统调用的过程 , 其实是发生了两次CPU上下文切换 。
CPU上下文切换 , 是保证Linux系统正常工作的核心功能之一 , 一般情况下不需要我们特别 。
但过多的上下文切换 , 会把CPU时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上 , 从而缩短进程真正运行的时间 , 导致系统的整体性能大幅下降 。