聊聊Linux中CPU上下文切换

目录

  • 什么是CPU上下文
  • CPU上下文切换
    • 上一任务的CPU上下文保存在哪?
  • 进程上下文切换
    • 内核空间和用户空间
    • top命令查看CPU资源
    • 系统调用
    • 进程上下文切换 和 系统调用的区别?
    • 进程切换的常见场景
  • 线程上下文切换
  • 中断上下文切换
  • 上下文切换的消耗
  • 补充:vmstat命令查看整体CPU上下文切换情况
  • 补充:pidstat命令查看进程的CPU上下文切换情况
作者:小牛呼噜噜 | https://xiaoniuhululu.com计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」
什么是CPU上下文Linux是一个多任务的操作系统,多任务操作系统是指多个进程运行在一个 CPU 中互不打扰,看起来像同时运行一样 。多任务的操作系统这样就可以支持远大于CPU数量的任务"同时运行" 。但是我们都知道这其实是一个错觉,真正是系统在很短的时间内将CPU轮流执行各个任务,给用户造成多任务"同时运行"的感觉 。其中有一个问题 , 在每次执行任务之前,CPU必须要知道从哪里加载任务 , 以及加载后从哪里开始运行,操作系统通过CPU中寄存器和程序计数器配合,来保存和恢复相应进度的信息
CPU 寄存器:CPU 寄存器是 CPU 内置的速度极快的内存;程序计数器:程序计数器会存储 CPU 正在执行的指令位置 , 或者即将执行的指令位置 。
在任务调度的过程中,而这些信息都保存在CPU的寄存器中 , 其中即将执行的下一条指令的地址被保存在程序计数器上 。我们将这些信息称为CPU的上下文,也叫硬件上下文 。当某一进程自愿放弃它的 CPU 时间或者系统分配的时间片用完时,就会发生CPU上下文切换 。
CPU上下文切换操作系统OS在切换运行任务时 , 将上一任务的上下文保存起来,然后加载新任务的上下文到CPU寄存器,最后再跳转到程序计数器所指的新位置上执行新任务的这一动作 , 被称为CPU上下文切换 。
CPU上下文切换的步骤:
  1. 将前一个 CPU 的上下文(也就是 CPU 寄存器和程序计数器里边的内容)保存起来;
  2. 然后加载新任务的上下文到寄存器和程序计数器;
  3. 最后跳转到程序计数器所指的新位置,运行新任务 。
  4. 被保存起来的上下文会存储到系统内核中,等待任务重新调度执行时再次加载进来 。
CPU 的上下文切换分三种:进程上下文切换、线程上下文切换、中断上下文切换
上一任务的CPU上下文保存在哪?我们知道因为CPU过于昂贵,其性能与其他储存设备有数量级的差距,为了充分压榨其性能 , 计算机将CPU的时间进行分片,让各个程序在CPU上轮转执行,被剥夺执行权的程序,等后面CPU继续执行它的时候,这时需要一个数据结构来保存相关信息,以便之后恢复继续执行 , 这个其实就是进程 。CPU上下文会被保存在进程的内核空间(kernel space)上 。OS在给每个进程分配虚拟内存空间时,会分配一个内核空间,这部分内存只能由内核代码访问 。OS在切换CPU上下文前,会先将当前CPU的通用寄存器、PC等进程现场信息保存在进程的内核空间上,待下次切换时,再取出重新装载到CPU上,以恢复任务的运行 。
聊聊Linux中CPU上下文切换

文章插图
进程上下文切换内核空间和用户空间我们知道为了限制不同的指令的访问能力,提升安全,Linux 按照特权等级,把进程的运行空间分为内核空间用户空间。进程既可以在用户空间运行,又可以在内核空间中运行 。进程在用户空间运行时,被称为进程的用户态 , 而陷入内核空间的时候,被称为进程的内核态
  1. 内核空间(Ring 0):具有最高权限,可以直接访问所有资源(读取文件)
常见的内核操作:分配内存、IO操作、创建子进程……
  1. 用户空间(Ring 3):只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用进入到内核中,才能访问这些特权资源

    推荐阅读