【Linux】进程属性:进程的状态

1.进程的状态

在说进程状态前,补充知识:

1.并行与并发

  • CPU在执行进程代码时,不是把一个进程代码执行完毕再去执行下一个进程,而是cup会给每一个进程分配一个时间片,cup基于这个时间片进行调度轮转(单CPU下)。
  • 单CPU下,CPU基于时间片进行轮转的策略(也就是进程切换),让多个进程在一段时间内,得以推进的一个情况被称作并发
  • CPU切换和运行的速度极快,用户感知不到,
  • 并行:多个进程在多个CPU下分别,同时进行运行

2.时间片

  • Linux/Windows这种民用级的操作系统,一般都是分时操作系统———>>调度任务追求的是公平。
  • 于此相对的还有实时操作系统,比如车载系统,例如在遇到危险时需要踩刹车,如果此时是分时操作系统,就会导致不能在第一时间进行踩刹车,如果是实时操作系统,就会提高踩刹车这一动作的优先级,让他先进行调度

3.进程具有独立性(上一节中有说明:进程的标识符)

  • 一个进程出现问题不会影响另一个进程,因为进程具有独立性
  • 多进程运行时互不干扰,需要独享各种资源

4.等待的本质(重点)(链入目标外设里,CPU不调度!!!)

1.OS给每一个CPU都会提供一个运行队列也就是struct_runqueue,这个结构体里面就会有一个task_struct指针,链接上所有被加载进来的进程的PCB,从而形成基于链式结构的调度队列,然后CPU就会基于时间片轮转进行进程调度

  • 所有什么是运行状态呢?只要进程在运行队列中,可以随时被调度,该进程就叫运行状态
  • 对进程的管理就变成对链表的增删查改

2.同时我们的OS也会对底层硬件进行管理,先描述再组织。每一个硬件设备对应一个结构体struct_device,然后通过链表结构链接起来,同时OS层面上定义一个指针指向第一个设备,从而可以访问到所有设备

我们的代码进程里面肯定会包含一些IO操作,也就是少不了一些外设的访问,根据冯诺依曼体系,只要我们不是在进行加减乘除这种简单的计算,剩下的大部分在进行访问外设操作。比如scanf,当CPU执行到scanf时,需要等待从键盘上获取数据,在这个等待的过程中就不能把该进程放入运行队列中,此时就要被设置为阻塞状态,当获取键盘数据就绪后,再次放回运行队列中。

那么怎么知道获取硬件设备数据就绪了呢?(linux中,新建就绪运行不做区分)

所以每一个设备描述结构体里,有一个指针task_struct *wait_queue来代表等待队列,当设备变成阻塞状态后,此时操作系统就要把该进程从运行队列里面剥夺下来,放入等待队列,等待硬件传来的数据。

当CPU调度运行到画圈的进程时执行到scanf()时,就会被剥夺下来链接到描述键盘设备的结构体对象中的wait_queue上变成阻塞状态,如果有多个进程需要从键盘访问数据,根据优先级依次以链式结构链接起来,在键盘上等待。

CPU调度进程才能运行推进代码,当链入到等待队列中,不会运行推进代码,等待硬件的数据,此时此时卡顿住。卡顿两种情况,要么CPU不调度了,要么进程太多,CPU调度不过来,上层用户就可以感知到卡顿。

那么当进程获取到从硬件传来的数据后,此时该进程PCB就要从等待队列中重新链入运行队列中继续被CPU调度运行。