Scott's world.

操作系统基础知识

Word count: 4.2kReading time: 14 min
2019/08/12 Share

学长的培训课件

操作系统基础

操作系统是管理计算机软硬件资源、合理安排计算机工作流程、提供给方便用户使用的接口的程序的集合。

这句话定义了操作系统的同时也告诉了我们操作系统的三大作用:

  1. 管理计算机软硬件资源
  2. 合理安排计算机工作流程
  3. 提供给方便用户使用的接口

操作系统领域的所有相关研究几乎都是为了解决这三个问题。

在整个计算机体系中,操作系统大概处于中间层的位置,向下对接硬件,向上对接软件。

不管你是使用Shell还是使用GUI,当你以为自己以及对所使用的操作系统了如指掌时,你可能只看到它的冰山一角。

看个数据

Windows 98有1500万行代码,Windows XP有3500万行代码,Windows Vista有5000万行代码,Windows 7有5000万行代码。

讲完下面的所有内容,你就该知道操作系统为我们解决了多少麻烦的工作。

注意:操作系统一样属于软件

进程与线程

进程

什么是进程?

进程是操作系统对一个正在运行的程序的一种抽象。

假设一种场景,你在使用视频编辑软件处理一个视频,因为渲染耗时太长,你把它放在后台开始使用word做其他工作,你又觉得单纯工作太无聊,于是打开了音乐播放软件开始一边听音乐一边写文档。

在这个过程中,你的电脑运行着三个进程(实际可能更多)。

一个单核CPU只能真正一次运行一个进程,如果你的电脑是单核CPU,那么这三个进程在不断地进行上下文切换以达成伪并行,当然这不是事实,实际上你的电脑CPU不止一个核,甚至你的电脑也不止有一个CPU,硬件的先进可以让你的电脑完成真正的进程并行

并行与并发

在同一时间同时执行多个进程叫做进程的并行,在同一时间段内执行多个进程叫做进程的并发。

他们的核心区别在于是否同时

进程与程序的区别

  • 进程是正在执行的程序,程序是静态的,而进程是动态的
  • 进程有并发的概念,程序没有
  • 一个程序可能生成多个进程

三态转换

上面提到,在单核CPU时代,进程通过不断的上下文切换实现伪并行,因此,进程的状态在不停的转换,所以有了下面的三态转换模型。

三态转换

在进行状态转换的时候,操作系统会保存进程运行时所需的所有状态信息(即上下文)。

线程

什么是线程?

传统操作系统中,每个进程有一个地址空间和和控制线程,控制线程安排一个进程内的任务执行顺序,后来随着进程内任务复杂度的增加,经常存在同一个地址空间中并行运行多个控制线程的情形。你完全可以类比进程的概念来理解线程。在整个操作系统中,由操作系统内核来安排进程调度,而在每一个进程中,由核心控制线程来安排进程内任务的执行,每一个任务又由一个线程来管理。

为什么要有多线程?

  1. 正如多进程可以共享系统资源,多线程共享同一个地址空间和所有可用数据的能力是必须的
  2. 线程比进程更轻量级,所以比进程更容易创建,也更容易撤销
  3. 如果存在大量计算和I/O处理,拥有多个线程允许这些活动彼此重叠进行,从而加快应用程序的执行速度
  4. 在多CPU系统中,多线程可以更大程度地利用这个优势

进程与线程的区别

  • 进程是资源分配的基本单位,线程是调度的基本单位
  • 进程有自己独立的代码和数据空间以及进程控制块(PCB),而线程共享进程的代码和数据空间
  • 每个线程有自己独立的程序计数器(PC)和寄存器堆栈
  • 线程可以在用户态实现,而进程的调度只能在内核态

进程间通信(IPC)

先来掌握几个基本概念

临界资源和临界区

当两个或多个进程需要同时使用某些共享数据时发生冲突,这些共享数据就称为临界资源,临界资源的访问代码称为临界区

直接制约与间接制约

  • 直接制约:进程间需要相互合作,一个进程的开始依赖于另一个进程的完成
  • 间接制约:进程间共享临界资源

同步与互斥

  • 进程间发生直接制约时,通过进程的同步保证正确执行

  • 进程间发生间接制约时,通过进程的互斥保证正确执行

进程并发时正确执行条件

  • 任何两个进程不能同时处于其临界区
  • 不应对 CPU 的速度和数量做任何假设
  • 临界区外运行的程序不得阻塞其他进程
  • 不得使进程无限期等待进入临界区

了解完上面几个概念之后,我们就该知道进程间通信是必须的,因为需要协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息,使得一个程序能够在同一时间里处理许多用户的要求。

信号量机制

对共享资源与临界区设立信号量,信号量可以取0或正值,通过进程间通信原语(down/up)操作信号量。

进程对一个信号量执行down操作,则是检查其值是否大于0,若大于0,则将该值减1并继续,若该值为0,则进程睡眠;up操作对信号量的值增1。down与up原语都是原子操作。

以生产者/消费者问题为例,生产者和消费者共用一个缓冲区,生产者向缓冲区放入数据,消费者从中读出数据,生产者和消费者有临界区,是互斥问题,生产者生产了数据之后消费者才能消费,进程间需要相互合作,是同步问题。设置mutex信号量,初值为1,empty信号量,初值为缓冲区可以放入的数据量大小,假定为N,full信号量,初值为0。

生产者生产时,需要对empty减1,即down(&empty),然后down(&mutex),(此时表示生产者进入临界区,mutex为0,消费者如果需要down(&mutex),会进入睡眠状态),生产者生产好数据后将其放入缓冲区,释放mutex,即up(&mutex),然后对full加1,即up(&full),生产者进程完成任务。

消费者消费时,需要对full减1,即即down(&full),然后down(&mutex),(此时表示消费者进入临界区,mutex为0,生产者如果需要down(&mutex),会进入睡眠状态),消费者消费完数据后,释放mutex,即up(&mutex),然后对empty加1,即up(&empty),消费者进程完成任务。

进程调度

当多个进程同时抢占CPU时,即多个进程同时处于就绪态,这种情形就会发生,如果只有一个CPU可用,那么就必须选择下一个要运行的进程,那么,选择哪一个?

完成这个选择工作的这一部分叫做调度程序,该程序使用的算法叫做调度算法

调度算法种类很多,不同的环境需要不同的调度算法,相同的环境不同情境下也需要不同的调度算法,所以算法没有优劣,关键在于什么时候使用,我们不说调度算法,只看准则。

所有系统下

  • 公平——给每个进程公平的CPU份额
  • 策略强制执行——保证规定的策略被执行
  • 平衡——保持系统的所有部分都忙碌

批处理系统

  • 吞吐量——每小时最大作业数
  • 周转时间——丛提交到终止间的最小时间
  • CPU利用率——保持CPU始终忙碌

交互式系统

  • 响应时间——快速响应请求
  • 均衡性——满足用户的期望

实时系统

  • 满足截至时间——避免丢失数据
  • 可预测性——在多媒体系统中避免品质降低

进程死锁

当我们解决间接制约问题时,一般会让共享资源只允许一个进程访问,所以有可能会产生下面这种情况

进程1占有资源A请求资源B,进程2占有资源B请求资源A,此时资源A只允许进程1访问,资源B只允许进程2访问,进程1、2都不能获取到自己需要的资源,但又不会释放自己拥有的资源,这种情况就称之为死锁

回到上面的生产者消费者问题,假如生产者进程在down(&mutex)和down(&empty)的顺序调换,即先down(&mutex)再down(&empty),假如此时empty为0,生产者进程睡眠,但它又占据着临界区,消费者无法进入消费,这就造成了死锁。

死锁的四个必要条件

  • 互斥条件:每个资源要么已经分配给了一个进程,要么就是可用的
  • 占有和等待条件:已经得到了某个资源的进程可以再请求新的资源
  • 不可抢占条件:已经分配给一个进程的资源不能强制性地被抢占,只能被显式释放
  • 环路等待条件:有两个或以上的进程组成环路,每个进程都等待下一个进程占有的资源

处理死锁的策略

  • 忽略该问题,也许如果你忽略它,它也会忽略你

  • 检测死锁并恢复

  • 仔细对资源分配,动态避免死锁
  • 破坏上述死锁必要条件

内存管理

内存管理的核心思想是存储器抽象。

接入几个概念理解一下这点

物理地址

无存储器抽象时程序直接访问的地址,是内存的真实地址反应

逻辑地址

有存储器抽象时程序访问的地址,地址空间就是其中一个例子,每个应用程序有自己独立的地址空间,程序访问的地址经过存储器抽象,映射到真正的物理地址(地址重定位)

虚拟内存

我们都想要更大的内存让自己的电脑能更快、更多地运行软件,但是事实上,软件所需占用的内存大小一直比内存的增长速度快,所以很有可能,内存的大小根本不足以运行软件,虚拟内存就是为了解决这个问题。

一个程序需要很大的内存,但是它并不是每时每刻都需要很大的内存,把它所有需要的内存分成多个块,每一块称为一个页面,在某个时刻需要的页面驻在内存中,而不需要的依旧在外存中,如果又需要另外的页面了,就把它从外存中调入。

这种技术就叫虚拟内存

页面置换算法

在某个时刻,需要某个程序的页面,但是这个页面不在内存中,这种情况称为缺页中断,发生缺页中断时,需要把页面从外存调入,但如果实际的物理内存不足以让原来的页面和需要的页面同时存在,就要用需要的页面去置换原来的页面,置换哪一个?

类似于上面的进程调度,完成选择工作的程序叫页面置换程序,采用的算法叫做页面置换算法,具体依旧不提,只要知道最好的页面置换算法往往换出的页面是最不需要的。

空闲内存管理

使用位图的存储管理

内存以固定大小分为若干分配单元,每个分配单元对应位图中的一位,0表示空闲,1表示占用

使用链表的存储管理

维护一个记录已分配内存段和空闲内存段的链表,链表的每一个节点都包含以下域:空闲区或进程的标志(H/P),起始地址、长度和指向下一节点的指针。

内存分配

新创建一个进程时,怎么为它分配内存,又是一套算法,内存分配算法,从空闲区中分配出内存,最好的结果是能最大程度地占用所有的空闲空间,不要留出无法使用的小空闲区。

文件管理

文件存储的介质是磁盘,多数磁盘划分为一个或多个分区,每个分区中有一个独立的文件系统。

磁盘的 0 号盘扇区称为主引导记录(Master Boot Record, MBR),用来引导计算机。在 MBR 的结尾是分区表,该表给出了每个分区的起始和结束地址。

表中的一个分区被标记为活动分区。在计算机被引导时,BIOS 读入并执行 MBR。MBR 做的第一件事是确定活动分区,读入它的第一个块,称为引导块,并执行。

引导块中的程序将装载该分区中的操作系统,为统一起见,每个分区都从一个引导块开始,即使它不含可启动的操作系统。

文件的实现

文件存储实现的关键是记录各个文件分别用哪些磁盘块,几个常见方法如下

连续分配

每个文件作为一连串数据块存储到磁盘上,这个方案的优势显而易见,记录一个文件用到的磁盘块,只需要知道它的第一块的磁盘地址和所占块数,而且读文件性能较高,一次寻找就可以找到文件所占的所有块。

但是缺点是,如果把文件删除,就会在磁盘上留下一个空闲块,会造成空间浪费。

链表分配

为每个文件构造磁盘块链表,每个块的第一个字作为指向下一块的指针,其他部分存放数据。

这个方案不会浪费空间,但是随机访问文件中的块比较缓慢。

内存中的表进行链表分配

把每个磁盘块的指针字放在内存中的一个表,称为文件分配表。

优势是整个链都存放在内存中,不需要磁盘引用,缺点是表放在内存中会占据大量内存空间。

i节点

每个文件赋予一个称为 i 节点(index-node)的数据结构,列出文件属性和文件快的磁盘地址,文件打开时,i节点存才在于内存中。

不会占据很多内存,又不会造成空间浪费。

I/O管理

I//O即输入/输出,在系统与外围设备之间发生,我们常见的I/O设备有键盘、鼠标、显示器、磁盘等。

I/O管理做的工作就是如何让CPU与外围设备更好地进行数据交流。

I/O软件层次

io

I/O实现方式

  • 程序控制I/O

  • 中断驱动I/O

  • 使用DMA的I/O

磁盘

磁盘被组织成柱面,每个柱面包含若干磁道,磁道又被分成若干扇区

RAID(廉价冗余磁盘阵列)

0-6级RAID

磁盘臂调度算法

读写磁盘块需要的时间由三个主要因素决定:寻道时间、旋转延迟、实际数据传输时间,其中主要的是寻道时间,因此减少寻道时间可以充分改善系统性能,如何得到最少的寻道时间,这就是磁盘臂调度算法的目的。

CATALOG
  1. 1. 操作系统基础
    1. 1.1. 进程与线程
      1. 1.1.1. 进程
        1. 1.1.1.1. 什么是进程?
        2. 1.1.1.2. 并行与并发
        3. 1.1.1.3. 进程与程序的区别
        4. 1.1.1.4. 三态转换
      2. 1.1.2. 线程
        1. 1.1.2.1. 什么是线程?
        2. 1.1.2.2. 为什么要有多线程?
        3. 1.1.2.3. 进程与线程的区别
      3. 1.1.3. 进程间通信(IPC)
        1. 1.1.3.1. 临界资源和临界区
        2. 1.1.3.2. 直接制约与间接制约
        3. 1.1.3.3. 同步与互斥
        4. 1.1.3.4. 进程并发时正确执行条件
        5. 1.1.3.5. 信号量机制
      4. 1.1.4. 进程调度
        1. 1.1.4.1. 所有系统下
        2. 1.1.4.2. 批处理系统
        3. 1.1.4.3. 交互式系统
        4. 1.1.4.4. 实时系统
      5. 1.1.5. 进程死锁
        1. 1.1.5.1. 死锁的四个必要条件
        2. 1.1.5.2. 处理死锁的策略
    2. 1.2. 内存管理
      1. 1.2.0.0.1. 物理地址
      2. 1.2.0.0.2. 逻辑地址
  2. 1.2.1. 虚拟内存
  3. 1.2.2. 页面置换算法
  4. 1.2.3. 空闲内存管理
    1. 1.2.3.1. 使用位图的存储管理
    2. 1.2.3.2. 使用链表的存储管理
    3. 1.2.3.3. 内存分配
  • 1.3. 文件管理
    1. 1.3.1. 文件的实现
      1. 1.3.1.1. 连续分配
      2. 1.3.1.2. 链表分配
      3. 1.3.1.3. 内存中的表进行链表分配
      4. 1.3.1.4. i节点
  • 1.4. I/O管理
    1. 1.4.1. I/O软件层次
      1. 1.4.1.1. I/O实现方式
    2. 1.4.2.
      1. 1.4.2.1. 磁盘
      2. 1.4.2.2. RAID(廉价冗余磁盘阵列)
      3. 1.4.2.3. 磁盘臂调度算法