多线程切换包含了哪些内容

148 阅读3分钟

前言

cpu 不知道什么是进程和线程,cpu 只知道两件事情

  1. 从内存中取出指令
  2. 执行指令
  3. 一直重复上面两个步骤,所以 取指令-> 执行指令 就是 cpu 所能做的所有事情

cpu 获取指令执行的流程

  1. 编写源代码,源代码中都会有 main 函数,这个 main 函数就是执行入口
  2. 程序启动后,会将 main 函数的第一条机器指令放入 pc 寄存器中(程序计数器)
  3. pc 寄存器的地址默认是自动 +1, 初始地址就是 main 函数的指令地址
  4. 当遇到 if else 等语句时程序会根据计算结果或者指令中指定的跳转地址来动态改变 pc 寄存器中的值

进程和线程的区别

  1. 进程是操作系统分配资源的最小单位
  2. 线程是调用的基本单位,线程之间共享进程资源
    1. 线程之间共享了哪些资源
      1. 堆区
      2. 代码区
      3. 数据区:存放的就是全局变量

什么是线程上下文

  1. 线程上下文就是指线程在某个时刻的状态,或者说某个时刻的数据,这个数据是线程私有的才能称为是线程的上下文
  2. 要看线程上下文包含哪些信息,就需要看哪些数据都是线程私有的,这些线程私有的数据整体就是线程上下文

线程的私有数据有哪些

线程本质就是函数的执行,函数执行的信息都是放在栈帧中,栈帧主要包含如下内容

  1. 当前函数的返回值
  2. 调用其他函数的参数(寄存器不够时参数是会放在栈帧中的)
  3. 函数使用的局部变量
  4. 函数使用的寄存器信息
  5. 程序计数器是线程私有的
  6. 栈指针(该线程栈区的栈顶位置)
  7. 执行函数时所使用的寄存器也是线程私有的

所有上面这些信息包含在一起就是线程上下文

线程上下文切换的流程

该部分内容参考 《Offer来了:Java面试核心知识点精讲(原理篇)》 3.7线程上下文切换

上下文切换指的是内核(操作系统的核心)在 CPU 上对进程或者线程进行切换 上下文切换过程中的信息被保存在进程控制块(PCB-Process Control Block)中。PCB 又被称作切换桢(SwitchFrame) 上下文切换的信息会一直被保存在 CPU 的内存中,直到被再次使用

上下文的切换流程如下

  • 挂起一个进程,将这个进程在 CPU 中的状态(上下文信息)存储于内存的 PCB
  • PCB 中检索下一个进程的上下文并将其在CPU的寄存器中恢复
  • 跳转到程序计数器所指向的位置(即跳转到进程被中断时的代码行)并恢复该进程

线程上下文切换到原因

  • 当前正在执行的任务完成,系统的CPU正常调度下一个任务
  • 当前正在执行的任务遇到I/O等阻塞操作,调度器挂起此任务,继续调度下一个任务
  • 多个任务并发抢占锁资源,当前任务没有抢到锁资源,被调度器挂起,继续调度下一个任务
  • 用户的代码挂起当前任务,比如线程执行sleep方法,让出CPU
  • 硬件中断

常用的几种寄存器

  1. 栈寄存器
    1. 函数运行时都有一个栈帧,对于栈来说重要的信息之一就是栈顶,栈寄存器就是保存栈顶信息的
  2. 指令寄存器(pc寄存器)
  3. 状态寄存器,线程是运行在内核态还是用户态的信息保存在状态寄存器中