运维工程师技能树-基础知识之操作系统篇(进程管理)

公众号:"打屎产品经理"  qq:1013896790  欢迎交流

运维工程师所需基础技能大体包含但不限于以下

  1. 操作系统
  2. 网络
  3. 常用开源组件
  4. 数据库
  5. 多语言编程技能
  6. 基础安全

越是复杂的场景,对于问题的分析能力以及基本功的要求越高,因此需要深入理解和熟练掌握。

操作系统:

  1. 进程管理
  • 核心数据结构-进程表

       首先进程是什么,进程是已经“跑起来”的程序,基本所有操作系统的教科书都会对进程和程序的区别大讲特讲。执行的脚本,运行的服务等都是进程。操作系统会为每个进程创建一个对象,每个进程对象分配一个进程id,叫做pid,相当于每个进程的身份证号,是进程的唯一标识。这个对象在实现上是一个结构体,这个结构体囊括了所有该进程所需要的所有属性和资源,包括程序运行的各个寄存器值,状态,内存指针,打开的文件描述符等等。当你执行一个程序时,操作系统会初始化一个这样的进程对象,然后为其分配所需的资源,并将这个进程对象作为一个表项挂到进程表上。

        进程表是一个链表,每个进程是这个链表上的一个结点,但是我们知道链表是不支持索引操作的,因此如果我们需要通过pid来查进程的信息就需要遍历整个进程表,效率比较低。为了解决这个问题,内核实现上为pid到进程对象又增加了一张hash表,这样就可以在常数时间内通过pid找到具体的进程了。这个设计很多人会迷惑,既然通过pid查找进程对象是一个常规操作,为什么在数据结构的选择上,进程表不采用数组而是采用链表+hash表呢?如果采用数组,则数组的长度应该设置为系统的最大进程数,这个值是非常难以确定的,如果设定太小,则会面临有时分配不出进程的情况。如果设定的太大,则内存资源又比较浪费,采用链表+hash表可以说是解决这个问题比较优雅的方式了。

        在进程对象的查找上除了通过pid索引的方式外,还支持通过亲属关系进行查找的方法,每个进程对象保存了孩子链表的指针和兄弟链表的指针,每个进程可以通过遍历孩子链表找到自己所有子进程。

       至此,我们已经看到了操作系统对于进程管理的核心数据结构-进程表,进程管理的工作抽象来看就是增删改查这个核心进程表,当然这只是一种便于理解但却不够严谨的解释,事实上的工作和细节非常之多。这里的介绍略过了很多操作系统设计上的细节,比如对于pid,当前的操作系统已经不是简单的在进程对象中以一个数字来标记,而是通过一个较为复杂的映射机制,映射出来的。对于pid的分配,内核的做法也与我们平时编程的惯用做法不相同,考虑到内存资源的利用及id复用,操作系统的pid分配器是基于位图来实现的。不过这些知识对于主干知识来讲,都算是支线,在搭建起基本的概念框架后再进行局部填充,这里不去进一步讨论,避免过早陷入细节。

  • 进程调度

        什么是进程调度,为什么要进程调度?进程调度就是内核决定把CPU拿给哪个进程使用的决策过程,由于CPU总是稀缺资源,为了有序高效的使用CPU,内核需要对它们进行调度。这里主要从2个方向进行说明,一个是调度的机制,另一个是调度的算法。调度机制说明内核是如何实现调度的,调度算法是说明内核如何计算出下一个可以占用CPU的进程是谁。

        进程调度机制,进程调度机制的最底层实现其实就是对寄存器的保存和更新,这个过程叫做上下文切换content switch,每个进程会将自己的运行现场保存在自己的task_struct对象里,操作系统只需要将上一个进程的运行现场保存到它的task_struct里,然后拿下一个进程的现场塞进寄存器即可,当然中间还会有一些细节。这个过程和函数调用有点类似,都需要保存现场和加载新的代码运行,不同的是函数调用的现场是保存在进程的栈上,且这个过程操作系统完全不需要参与。这个是对调度机制的一个最简化抽象,实际的实现要复杂很多,linux的调度器结构如下

运维工程师技能树-基础知识之操作系统篇(进程管理)_第1张图片

主调度器和周期性调度器统称核心调度器,主调度器完成直接调度,比如进程的主动让出cpu,周期性调度器对进程进行周期性扫描以观察是否有进程需要切换。核心调度器调用调度器类得知下一个要运行的进程是谁,然后执行具体的进程切换工作。调度器类用于实现不同的调度算法,这样策略和机制就完美分开了。

        进程调度算法,linux支持完全公平调度类和实时调度类两大类调度算法,完全公平调度算法以进程的运行时间作为key然后进行排队,消耗小的排在队列的前面。优先级不同的任务,虚拟时间的增长不同,优先级高的涨的慢,这样它运行完后根据消耗时间来排序,它可以插队到前面,马上又获得CPU来运行。实时调度类主要是两种算法,RR和FIFO,分别根据时间片轮转来获得CPU,优先级高的可以抢占优先级低的。FIFO则是每个进程要运行到自己放弃CPU为止。

 

 

你可能感兴趣的:(运维技能树)