2023-03-31
操作系统
00
请注意,本文编写于 663 天前,最后修改于 663 天前,其中某些信息可能已经过时。

目录

进程管理
进程
进程的状态
创建进程
上下文切换
进程上下文切换
线程
线程定义
进程和线程的比较
进程的上下文切换
线程的实现

进程管理

进程

我们编写的代码只是一个存储在硬盘里的静态文件,通过编译可执行的二进制文件,当运行这个文件时,会被装载到内存中,接着CPU会执行程序中的每一条指令,那么这个运行中的程序,就被称为进程

如果程序中存在读写硬盘文件的代码,那么执行该指令时,由于读写速度很慢,如果CPU要等待读写得到的数据的话,那CPU利用率就是非常低的,所以要想办法在等待时机内去做其他的事,而收到通知后再回来继续,这个通知就是中断

进程的状态

最基本的三个是运行-阻塞-就绪,除此之外还有创建和结束状态

一个完整的进程状态变迁是:

图片.png

  • 一个进程被创建时进入创建状态
  • 创建完并完成初始化后,变为就绪状态
  • 就绪状态被操作系统的进程调度器选中后,就分配给CPU正式运行该进程,进入运行状态
  • 进程完成或者出错以后,会被操作系统作结束状态处理
  • 处于运行状态的进程在运行过程中,由于分配给的运行时间片用完,重新回到就绪态
  • 当进程请求某个事件,遇到阻塞必须等待的时候,例如IO事件,或者等待资源,就会进入阻塞状态
  • 当进程等待的事件完成后,会从阻塞状态恢复就绪状态

且通常情况下,如果阻塞状态的进程过多,会占用很大的物理空间,所以一般会将阻塞的进程的物理内存空间移出到硬盘,等需要的时候再从硬盘移入物理内存,这个状态就是挂起,用来描述进程没有占用实际的物理内存空间的情况

  • 阻塞挂起

进程在外存并等待某个事件的出现

  • 就绪挂起

进程在外存,但只要进入内存即立刻运行

导致进程挂起的原因:

  • 进程所使用的内存空间不在物理内存
  • 通过sleep让进程间歇性挂起
  • 用户用ctrl+z挂起一个程序的进程

创建进程

  1. 创建进程

操作系统允许一个进程创建另外一个进程,而且允许子进程继承父进程所拥有的资源

过程如下:

  • 申请一个空白的PCB,并向PCB里填入控制和管理进程的信息,比如进程唯一标识等
  • 为该进程分配运行时需要的资源,比如内存资源
  • 将PCB插入到就绪队列,等待被调用
  1. 终止进程
  • 正常结束、异常结束以及外界干预(信号kill掉)

当子进程被终止,从父进程处继承来的资源会归还给父进程,而当父进程被终止时,子进程会被变为孤儿进程,会被1号进程收养,并且由1号进程对它们完成状态收集工作

终止进程的过程:

  • 查找需要终止进程的PCB
  • 如果处于执行状态,则停止进程执行,释放CPU资源
  • 如果其有子进程,则将子进程交给1号进程管理
  • 将该进程资源全部释放
  • 从PCB所在队列中删除
  1. 阻塞进程

当进程在等待其余事件时,它可以采用阻塞语句将自己阻塞,而一旦被阻塞等待只能由另外一个进程唤醒

过程如下:

  • 找到要被阻塞进程标识号对应的PCB
  • 如果该进程为运行状态,则保护现场,将状态转为阻塞状态,停止运行
  • 将该PCB插入到阻塞队列
  1. 唤醒进程

阻塞态无法自己唤醒自己,所以需要等待其他进程的唤醒

过程如下:

  • 在该事件的阻塞队列中找到相应进程的PCB
  • 将其从阻塞队列中移出,并置状态为就绪状态
  • 把该PCB插入到就绪队列中,等待调度程序调度

上下文切换

各个进程之间是共享CPU资源的,在不同的时候进程之间需要切换,让不同的进程可以在CPU执行,这个切换的过程就称为上下文切换

每个任务执行前,CPU需要知道任务从哪里加载,从哪里开始运行,所以操作系统需要帮助CPU设置好CPU寄存器程序计数器

程序计数器就是用来存储CPU正在执行的指令位置,或者即将执行的下一条指令位置,这些环境就是上下文

即在运行前必须依赖的环境

进程上下文切换

进程是由内核管理和调度的,所以进程的切换只能发生在内核态

所以,进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈,寄存器等内核空间的资源,通常把交换的信息保存在PCB中,运行另外一个进程时就会把信息从PCB中取出,加载到CPU中

发生场景

  • 时间片轮转,时间片耗尽了就进入就绪状态
  • 系统资源不足的时候,要等待资源满足后才可以运行,这个时候进程也会进行挂起
  • 当进程通过sleep主动挂起,也会重新调度
  • 当高优先级的进程运行,则当前进程被挂起
  • 发生硬件中断时,也会挂起,执行内核中的中断服务程序

线程

为什么要有线程?那自然是进程有缺点需要满足

比如一个程序,如果有多个操作,例如视频对话,首先需要读取文件,然后再进行解压缩,最后再播放,如果视频比较大,就需要在IO读取部分耗时过久,如果每个进程各执行一个功能,又需要实现进程之间的通信,共享数据,所以会很麻烦,而且维护进程的系统开销比较大

所以为了让实体之间可以并发运行,而且共享相同的地址空间,人们就发明了一个新的实体,线程,可以并发运行而且共享相同的内存空间

线程定义

线程是进程当中的一条执行流程

每个线程各自有一套独立的寄存器和栈,这样可以确保线程的控制流是独立的,而且共享代码段,数据段,解决了通信和数据共享的问题

进程和线程的比较

  • 进程是资源分配的单位,线程是CPU调度的单位

  • 进程拥有一个完整的资源平台,线程只独享必不可少的资源,如寄存器和栈

  • 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系

  • 线程能减少并发执行的空间和时间开销

  • 线程的创建耗时少,它不需要像进程一样再去创建需要的一些信息,比如内存管理、文件管理信息等,它们只需要共享这些资源即可

  • 线程终止时间比进程快,因为释放的资源少

  • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间,意味着同一个进程的线程都具有同一个页表,而进程切换的时候需要把页表给进行切换,页表切换的开销就会比较大

  • 共享了文件和内存,线程之间就不需要通过内核传输数据了

进程的上下文切换

操作系统的任务调度实际上调度的是线程,而进程只是给线程提供了虚拟内存和全局变量等资源

而线程独有的资源就是其栈和寄存器,如果是两个不同进程的线程切换,则和进程上下文切换一样,否则的话只需要切换私有数据,寄存器等数据

线程的实现

  • 用户线程

在用户空间实现的线程,不是由内核管理的线程,是由用户态的线程库来完成线程的管理

  • 内核线程

在内核中实现的线程,是由内核管理的线程

  • 轻量级进程

在内核中支持用户线程

本文作者:Malyue

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!