读《计算机的心智》,另一个角度看操作系统

关于进程

进展中的程序,一个程序被加载到内存后就变成进程。对于操作系统,进程是其提供的一种抽象,目的是通过并发提高系统CPU利用率,缩短响应时间。

  • 进程的三种典型状态

image

  • 进程的创建过程

    1. 分配进程控制块
    2. 初始化机器寄存器
    3. 初始化页表
    4. 将程序代码从磁盘读取到内存
    5. 将处理器状态设置为用户态
    6. 跳转到程序的起始地址(设置程序计数器)

UNIX 创建进程:1.fork[创建一个与自己完全一样的新进程] 2.exec[新进程的地址空间用另一个程序覆盖,跳转到新进程的起始地址完成启动]

Window CreateProcess函数:CreateProcess[传递进来新的程序名称,创建新的页表]


进程调度

  • 程序使用CPU的三种模式

    1. 计算密集型(科学计算,矩阵乘法…)
    2. IO密集型(游戏,人机交互…)
    3. 平衡程序(网页浏览,下载,网络视频…)
  • 进程调度的目标

极小化平均响应时间,极大化系统吞吐,保持各个系统功能部件处于繁忙和维持公平机制。


进程调度算法

  • First Come First Server(先来先服务算法)

顾名思义…

  • 时间片轮转算法

周期性地进行进程切换…

  • Shorted Time to Completion First(短任务优先算法)

非抢占式:CPU上的程序运行到阻塞或者结束,从候选程序中选择执行时间最短的进行执行。 抢占式:新增一个进程时,就从所有进程中选择执行时间最短的运行。

  • 优先级调度算法

对每个进行赋予优先级,按照优先级调度

  • 保证调度算法

众生平等策略,如果系统有n个进程,保证每个进程的CPU占用时间为1/n。

  • 实时调度算法

    1. 动态优先调度(EDF) 动态计算每个任务的截止时间进行动态调度优先级。由STCF算法改进而来,EDF就是最早截至的任务先运行,如果新进程比正在运行的进程的截止时间更靠前,就抢占当前任务进行调度。

    缺陷:需要动态计算任务截止时间,消耗CPU资源,所以就有了静态调度算法

    1. 静态优先调度(RMS) 在进行调度之前,先计算出所有任务的优先级,按照计算的优先级进行调度,任务执行过程中不接受新进程也不进行优先级调整与CPU抢占。

    缺陷:没有动态优先调度灵活


进程通信(IPC)

  • 管道通信(类UNIX下) 通过Shell的 | :sort < file |grep li [在排序sort与查找grep之间建立管道。数据从sort流向grep,作用是对file进行排序,排序结果作为grep程序的输入,在结果中找出包括li的文本行]

通过pipe函数

管道:用于管道的读与写。半双工的,具有固定的读端和写端(他只能用于具有亲缘关系的进程之间的通信)。可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

  • FIFO(命名管道,是一种文件类型) FIFO可以在无关的进程之间交换数据,与无名管道不同。

FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

  • Socket套接字 分为本地(UNIX域)套接字,网域套接字

  • 信号 利用CPU内中断进行通信

在计算机里,信号就是一个内核对象(数据结构)。发送方将该数据结构的内容填好,并指明该信号的目标进程后,发出特定的软件中断。操作系统接收到特定的中断请求后,知道是有进程要发送信号,于是到特定的内核数据结构里查找信号接收方,并进行通知。接到通知的进程则对信号进行相应处理。

  • 共享内存 …

  • 消息队列 无固定读写进程,支持多进程,多对多而并非管道之类的点对点。 消息队列是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

image

  • 参考:

https://songlee24.github.io/2015/04/21/linux-IPC/

权衡

  • 管道通信,Socket套接字消耗系统资源大
  • 信号:小数据量通信
  • 共享内存,消息队列:大数据量通信