终于理解了进程切换慢的真正原因。

上下文:运行的状态、环境

进程

操作系统对运行的应用程序的抽象,进程的运行空间分为用户态和内核态,执行内核相关操作时,要进入内核态。

程序是被动实体,而进程是主动实体。一次只有一个进程可以在一个处理器上运行。

进程内存空间的组成包括:

  • 用户栈:保存进程需要使用的各种临时数据,自顶向下扩展
  • 代码库:进程执行有时需要依赖共享的代码库,这些代码库被映射到用户栈下方的虚地址处,标记为只读。
  • 用户堆:堆管理的是进程动态分配的内存。字下向上扩展。
  • 数据与代码段:他们原本保存在进程需要执行的 二进制文件中,进程执行前,操作系统将他们载入虚拟地址中。数据段都是全局变量
  • 内核部分:位于进程地址空间的最顶端,只有当进程进入内核态时,才能访问内核内存,内核部分也有代码段与数据段。

进程的上下包括哪些:

  • 堆栈
  • 寄存器
  • 代码和数据
  • 内存

进程的想关状态用进程标识符PID保存,包括进程状态、虚拟内存状态、打开的文件。

进程切换过程:将进程的上下文信息保存在其对应的PCB中,接着将要切换到的进程的PCB中的数据恢复出来,开始执行。

img

线程

为什么要有线程

  • 创建进程开销大:创建独立的地址空间、载入数据和代码段、初始化堆
  • 进程间数据共享和同步麻烦,只能通过共享虚拟内存页(粒度粗)或基于进程间通信(开销大)

线程是在进程内部的可独立执行的单元,线程之间有独立的寄存器、堆栈但是共享数据、代码段和堆

在创建过程中,线程不需要分配内存空间,而进程需要,所以线程创建比进程快。

线程分为两类:
image

image

  • 用户态线程:由应用自己创建,内核不可见,更轻量、开销更小,功能受限
  • 内核态线程:由内核创建,受操作系统调度器管理

用户态线程功能受限,因此与内核态相关的操作,需要内核态线程协助。然后操作系统会建立起两种线程之间的关系,常见的由一对多,一对一,多对多,对字前面的是内核态线程。linux采用一对一模型

线程切换

类似与进程,线程有线程控制块TCB,在一对一模型中,内核态线程用户态线程各自保存自己的TCB。

线程切换只涉及程序计数器、寄存器、堆栈的切换,线程切换的消耗主要是进出内核的消耗。

为什么线程切换比进程切换快

因为进程切换比线程切换多了页表的切换(操作系统为每个进程搞一张页表,可能一级也可能多级),而页表切换会导致TLB失效,TLB中的内容要全部重写,所以所以慢了,切换页表很快,就是个指针的问题,内存变动也不是原因。

posted @ 2022-03-21 21:37  博客是个啥?  阅读(465)  评论(0编辑  收藏  举报