当前位置: > 财经>正文

5万字、97 张图总结操作系统核心知识点 基金知识点总结归纳图表

2023-08-22 22:52:02 互联网 未知 财经

文末领取大图。

这不是一篇教你如何创建一个操作系统的文章,相反,这是一篇指导性文章,教你从几个方面来理解操作系统。首先你需要知道你为什么要看这篇文章以及为什么要学习操作系统。

搞清楚几个问题

首先你要搞明白你学习操作系统的目的是什么?操作系统的重要性如何?学习操作系统会给我带来什么?下面我会从这几个方面为你回答下。

操作系统也是一种软件,但是操作系统是一种非常复杂的软件。操作系统提供了几种抽象模型

文件:对 I/O 设备的抽象虚拟内存:对程序存储器的抽象进程:对一个正在运行程序的抽象虚拟机:对整个操作系统的抽象

这些抽象和我们的日常开发息息相关。搞清楚了操作系统是如何抽象的,才能培养我们的抽象性思维和开发思路。

很多问题都和操作系统相关,操作系统是解决这些问题的基础。如果你不学习操作系统,可能会想着从框架层面来解决,那是你了解的还不够深入,当你学习了操作系统后,能够培养你的全局性思维。

学习操作系统我们能够有效的解决并发问题,并发几乎是互联网的重中之重了,这也从侧面说明了学习操作系统的重要性。

学习操作系统的重点不是让你从头制造一个操作系统,而是告诉你操作系统是如何工作的,能够让你对计算机底层有所了解,打实你的基础。

相信你一定清楚什么是编程

Data structures + Algorithms = Programming

操作系统内部会涉及到众多的数据结构和算法描述,能够让你了解算法的基础上,让你编写更优秀的程序。

我认为可以把计算机比作一栋楼

计算机的底层相当于就是楼的根基,计算机应用相当于就是楼的外形,而操作系统就相当于是告诉你大楼的构造原理,编写高质量的软件就相当于是告诉你构建一个稳定的房子。

认识操作系统

在了解操作系统前,你需要先知道一下什么是计算机系统:现代计算机系统由一个或多个处理器、主存、打印机、键盘、鼠标、显示器、网络接口以及各种输入/输出设备构成的系统。这些都属于硬件的范畴。我们程序员不会直接和这些硬件打交道,并且每位程序员不可能会掌握所有计算机系统的细节。

所以计算机科学家在硬件的基础之上,安装了一层软件,这层软件能够根据用户输入的指令达到控制硬件的效果,从而满足用户的需求,这样的软件称为 操作系统,它的任务就是为用户程序提供一个更好、更简单、更清晰的计算机模型。也就是说,操作系统相当于是一个中间层,为用户层和硬件提供各自的借口,屏蔽了不同应用和硬件之间的差异,达到统一标准的作用。

上面一个操作系统的简化图,最底层是硬件,硬件包括芯片、电路板、磁盘、键盘、显示器等我们上面提到的设备,在硬件之上是软件。大部分计算机有两种运行模式:内核态 和 用户态,软件中最基础的部分是操作系统,它运行在 内核态 中。操作系统具有硬件的访问权,可以执行机器能够运行的任何指令。软件的其余部分运行在 用户态 下。

在大概了解到操作系统之后,我们先来认识一下硬件都有哪些

计算机硬件

计算机硬件是计算机的重要组成部分,其中包含了 5 个重要的组成部分:运算器、控制器、存储器、输入设备、输出设备。

运算器:运算器最主要的功能是对数据和信息进行加工和运算。它是计算机中执行算数和各种逻辑运算的部件。运算器的基本运算包括加、减、乘、除、移位等操作,这些是由 算术逻辑单元(Arithmetic&logical Unit) 实现的。而运算器主要由算数逻辑单元和寄存器构成。控制器:指按照指定顺序改变主电路或控制电路的部件,它主要起到了控制命令执行的作用,完成协调和指挥整个计算机系统的操作。控制器是由程序计数器、指令寄存器、解码译码器等构成。

运算器和控制器共同组成了 CPU

存储器:存储器就是计算机的记忆设备,顾名思义,存储器可以保存信息。存储器分为两种,一种是主存,也就是内存,它是 CPU 主要交互对象,还有一种是外存,比如硬盘软盘等。下面是现代计算机系统的存储架构

输入设备:输入设备是给计算机获取外部信息的设备,它主要包括键盘和鼠标。

输出设备:输出设备是给用户呈现根据输入设备获取的信息经过一系列的计算后得到显示的设备,它主要包括显示器、打印机等。

这五部分也是冯诺伊曼的体系结构,它认为计算机必须具有如下功能:

把需要的程序和数据送至计算机中。必须具有长期记忆程序、数据、中间结果及最终运算结果的能力。能够完成各种算术、逻辑运算和数据传送等数据加工处理的能力。能够根据需要控制程序走向,并能根据指令控制机器的各部件协调操作。能够按照要求将处理结果输出给用户。

下面是一张 intel 家族产品图,是一个详细的计算机硬件分类,我们在根据图中涉及到硬件进行介绍

总线(Buses):在整个系统中运行的是称为总线的电气管道的集合,这些总线在组件之间来回传输字节信息。通常总线被设计成传送定长的字节块,也就是 字(word)。字中的字节数(字长)是一个基本的系统参数,各个系统中都不尽相同。现在大部分的字都是 4 个字节(32 位)或者 8 个字节(64 位)。

I/O 设备(I/O Devices):Input/Output 设备是系统和外部世界的连接。上图中有四类 I/O 设备:用于用户输入的键盘和鼠标,用于用户输出的显示器,一个磁盘驱动用来长时间的保存数据和程序。刚开始的时候,可执行程序就保存在磁盘上。

每个I/O 设备连接 I/O 总线都被称为控制器(controller) 或者是 适配器(Adapter)。控制器和适配器之间的主要区别在于封装方式。控制器是 I/O 设备本身或者系统的主印制板电路(通常称作主板)上的芯片组。而适配器则是一块插在主板插槽上的卡。无论组织形式如何,它们的最终目的都是彼此交换信息。

主存(Main Memory),主存是一个临时存储设备,而不是永久性存储,磁盘是 永久性存储 的设备。主存既保存程序,又保存处理器执行流程所处理的数据。从物理组成上说,主存是由一系列 DRAM(dynamic random access memory) 动态随机存储构成的集合。逻辑上说,内存就是一个线性的字节数组,有它唯一的地址编号,从 0 开始。一般来说,组成程序的每条机器指令都由不同数量的字节构成,C 程序变量相对应的数据项的大小根据类型进行变化。比如,在 Linux 的 x86-64 机器上,short 类型的数据需要 2 个字节,int 和 float 需要 4 个字节,而 long 和 double 需要 8 个字节。

处理器(Processor),CPU(central processing unit) 或者简单的处理器,是解释(并执行)存储在主存储器中的指令的引擎。处理器的核心大小为一个字的存储设备(或寄存器),称为程序计数器(PC)。在任何时刻,PC 都指向主存中的某条机器语言指令(即含有该条指令的地址)。

从系统通电开始,直到系统断电,处理器一直在不断地执行程序计数器指向的指令,再更新程序计数器,使其指向下一条指令。处理器根据其指令集体系结构定义的指令模型进行操作。在这个模型中,指令按照严格的顺序执行,执行一条指令涉及执行一系列的步骤。处理器从程序计数器指向的内存中读取指令,解释指令中的位,执行该指令指示的一些简单操作,然后更新程序计数器以指向下一条指令。指令与指令之间可能连续,可能不连续(比如 jmp 指令就不会顺序读取)

下面是 CPU 可能执行简单操作的几个步骤

加载(Load):从主存中拷贝一个字节或者一个字到内存中,覆盖寄存器先前的内容存储(Store):将寄存器中的字节或字复制到主存储器中的某个位置,从而覆盖该位置的先前内容操作(Operate):把两个寄存器的内容复制到 ALU(Arithmetic logic unit) 。把两个字进行算术运算,并把结果存储在寄存器中,重写寄存器先前的内容。

算术逻辑单元(ALU)是对数字二进制数执行算术和按位运算的组合数字电子电路。

跳转(jump):从指令中抽取一个字,把这个字复制到程序计数器(PC) 中,覆盖原来的值进程和线程

关于进程和线程,你需要理解下面这张脑图中的重点

进程

操作系统中最核心的概念就是 进程,进程是对正在运行中的程序的一个抽象。操作系统的其他所有内容都是围绕着进程展开的。

在多道程序处理的系统中,CPU 会在进程间快速切换,使每个程序运行几十或者几百毫秒。然而,严格意义来说,在某一个瞬间,CPU 只能运行一个进程,然而我们如果把时间定位为 1 秒内的话,它可能运行多个进程。这样就会让我们产生并行的错觉。因为 CPU 执行速度很快,进程间的换进换出也非常迅速,因此我们很难对多个并行进程进行跟踪。所以,操作系统的设计者开发了用于描述并行的一种概念模型(顺序进程),使得并行更加容易理解和分析。

进程模型

一个进程就是一个正在执行的程序的实例,进程也包括程序计数器、寄存器和变量的当前值。从概念上来说,每个进程都有各自的虚拟 CPU,但是实际情况是 CPU 会在各个进程之间进行来回切换。

如上图所示,这是一个具有 4 个程序的多道处理程序,在进程不断切换的过程中,程序计数器也在不同的变化。

在上图中,这 4 道程序被抽象为 4 个拥有各自控制流程(即每个自己的程序计数器)的进程,并且每个程序都独立的运行。当然,实际上只有一个物理程序计数器,每个程序要运行时,其逻辑程序计数器会装载到物理程序计数器中。当程序运行结束后,其物理程序计数器就会是真正的程序计数器,然后再把它放回进程的逻辑计数器中。

从下图我们可以看到,在观察足够长的一段时间后,所有的进程都运行了,但在任何一个给定的瞬间仅有一个进程真正运行。

因此,当我们说一个 CPU 只能真正一次运行一个进程的时候,即使有 2 个核(或 CPU),每一个核也只能一次运行一个线程。

由于 CPU 会在各个进程之间来回快速切换,所以每个进程在 CPU 中的运行时间是无法确定的。并且当同一个进程再次在 CPU 中运行时,其在 CPU 内部的运行时间往往也是不固定的。

这里的关键思想是认识到一个进程所需的条件,进程是某一类特定活动的总和,它有程序、输入输出以及状态。

进程的创建

操作系统需要一些方式来创建进程。下面是一些创建进程的方式

系统初始化(init):启动操作系统时,通常会创建若干个进程。正在运行的程序执行了创建进程的系统调用(比如 fork)用户请求创建一个新进程:在许多交互式系统中,输入一个命令或者双击图标就可以启动程序,以上任意一种操作都可以选择开启一个新的进程,在基本的 UNIX 系统中运行 X,新进程将接管启动它的窗口。初始化一个批处理工作

从技术上讲,在所有这些情况下,让现有流程执行流程是通过创建系统调用来创建新流程的。该进程可能是正在运行的用户进程,是从键盘或鼠标调用的系统进程或批处理程序。这些就是系统调用创建新进程的过程。该系统调用告诉操作系统创建一个新进程,并直接或间接指示在其中运行哪个程序。

在 UNIX 中,仅有一个系统调用来创建一个新的进程,这个系统调用就是 fork。这个调用会创建一个与调用进程相关的副本。在 fork 后,一个父进程和子进程会有相同的内存映像,相同的环境字符串和相同的打开文件。

在 Windows 中,情况正相反,一个简单的 Win32 功能调用 CreateProcess,会处理流程创建并将正确的程序加载到新的进程中。这个调用会有 10 个参数,包括了需要执行的程序、输入给程序的命令行参数、各种安全属性、有关打开的文件是否继承控制位、优先级信息、进程所需要创建的窗口规格以及指向一个结构的指针,在该结构中新创建进程的信息被返回给调用者。在 Windows 中,从一开始父进程的地址空间和子进程的地址空间就是不同的。

进程的终止

进程在创建之后,它就开始运行并做完成任务。然而,没有什么事儿是永不停歇的,包括进程也一样。进程早晚会发生终止,但是通常是由于以下情况触发的

正常退出(自愿的) : 多数进程是由于完成了工作而终止。当编译器完成了所给定程序的编译之后,编译器会执行一个系统调用告诉操作系统它完成了工作。这个调用在 UNIX 中是 exit ,在 Windows 中是 ExitProcess。错误退出(自愿的):比如执行一条不存在的命令,于是编译器就会提醒并退出。严重错误(非自愿的)被其他进程杀死(非自愿的) : 某个进程执行系统调用告诉操作系统杀死某个进程。在 UNIX 中,这个系统调用是 kill。在 Win32 中对应的函数是 TerminateProcess(注意不是系统调用)。进程的层次结构

在一些系统中,当一个进程创建了其他进程后,父进程和子进程就会以某种方式进行关联。子进程它自己就会创建

版权声明: 本站仅提供信息存储空间服务,旨在传递更多信息,不拥有所有权,不承担相关法律责任,不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请发送邮件至 举报,一经查实,本站将立刻删除。