操作系统也是一门比较重要的学科。为何这样说呢?
操作系统中的很多思想、很多经典的算法,你都可以在我们日常开发使用的各种工具或者框架中找到它们的影子。
比如说我们开发的系统使用的缓存(比如 Redis)和操作系统的高速缓存就很像。CPU 中的高速缓存有很多种,不过大部分都是为了解决 CPU 处理速度和内存处理速度不对等的问题。我们还可以把内存可以看作外存的高速缓存,程序运行的时候我们把外存的数据复制到内存,由于内存的处理速度远远高于外存,这样提高了处理速度。同样地,我们使用的 Redis 缓存就是为了解决程序处理速度和访问常规关系型数据库速度不对等的问题。
高速缓存一般会按照局部性原理(2-8 原则)根据相应的淘汰算法保证缓存中的数据是经常会被访问的。我们平常使用的 Redis 缓存很多时候也会按照 2-8 原则去做,很多淘汰算法都和操作系统中的类似。
既说了 2-8 原则,那就不得不提命中率了,这是所有缓存概念都通用的。简单来说也就是你要访问的数据有多少能直接在缓存中直接找到。命中率高的话,一般表明你的缓存设计比较合理,系统处理速度也相对较快。
总结来说,我觉得学好操作系统除了能够加深自己对于操作系统的了解/程序运行的底层机制,还能够提高自己思考的深度以及对技术的理解力,培养全局性思维。
下面我们系统的了解一下操作系统:
1、什么是操作系统?
操作系统(operation system,简称OS)是管理计算机硬件与软件资源的计算机程序。 它主要实现:
* 文件:对 I/O 设备的抽象
* 虚拟内存:对程序存储器的抽象
* 进程:对一个正在运行程序的抽象
* 虚拟机:对整个操作系统的抽象
通俗的理解,操作系统是在计算机上运行的最重要的软件,它管理着计算机的内存和进程,以及所有的软件和硬件。它还允许你在不知道如何说出计算机语言的情况下与计算机进行交流。没有操作系统,计算机就毫无用处。
2、操作系统的职责
在了解操作系统前,你需要先知道一下什么是计算机系统:现代计算机系统由一个或多个处理器、主存、打印机、键盘、鼠标、显示器、网络接口以及各种输入/输出设备构成的系统。这些都属于硬件的范畴。我们程序员不会直接和这些硬件打交道,并且每位程序员不可能会掌握所有计算机系统的细节。
所以计算机科学家在硬件的基础之上,安装了一层软件,这层软件能够根据用户输入的指令达到控制硬件的效果,从而满足用户的需求,这样的软件称为 操作系统,它的任务就是为用户程序提供一个更好、更简单、更清晰的计算机模型。也就是说,操作系统相当于是一个中间层,为用户层和硬件提供各自的借口,屏蔽了不同应用和硬件之间的差异,达到统一标准的作用。
上面一个操作系统的简化图,最底层是硬件,硬件包括芯片、电路板、磁盘、键盘、显示器等我们上面提到的设备,在硬件之上是软件。大部分计算机有两种运行模式:内核态 和 用户态,软件中最基础的部分是操作系统,它运行在 内核态 中。操作系统具有硬件的访问权,可以执行机器能够运行的任何指令。软件的其余部分运行在 用户态 下。
操作系统位于底层硬件与用户之间,是两者沟通的桥梁。用户可以通过操作系统的用户界面,输入命令。操作系统则对命令进行解释,驱动硬件设备,实现用户要求。以现代标准而言,一个标准PC的操作系统应该提供以下的功能:
* 进程管理(Processing management)
* 内存管理(Memory management)
* 文件系统(File system)
* 网络通信(Networking)
* 安全机制(Security)
* 用户界面(User interface)
* 驱动程序(Device drivers)
进程管理:负责进程运行优先级,进程之间通信,进程异常终止处理以及死锁(Dead Lock)侦测及处理等功能。
内存管理:负责提供查找可用的记忆空间、配置与释放记忆空间以及交换存储器和低速存储设备等功能
磁盘与文件系统:通常指称管理磁盘资料的系统,可将资料以目录或文件的型式存储。
安全:权限,授权,认证等。分内部通信和外部通信安全。
用户界面:GUI图形界面(主流),CLI命令行界面
驱动:与硬件交互的软件,操作系统和硬件的中间层。通常是一个设备交互接口,将消息提供给操作系统和应用程序。驱动的主要目的是操作的抽象化。比如操作系统是固定的windows,但是硬盘和cpu等硬件有很多不同的生产厂商,为解决此问题操作系统会主动制订每种设备该有的操作方式,而驱动程序功能则是将那些操作系统制订的行为描述,转译为可让设备了解的自定义操作手法。
3、操作系统类型
操作系统通常已被预装在你购买的任何计算机上。大多数人使用计算机附带的操作系统,但可以将之升级甚至更改操作系统。个人计算机最常用的三种操作系统是微软Microsoft Windows,苹果Mac OS X和Linux。
现代操作系统使用图形用户界面(简称GUI,区别于命令行界面CLI)。 GUI允许你使用鼠标来点击图标、按钮和菜单选项。所有内容都用图形和文本的组合方式被清晰地显示在屏幕上。
移动设备操作系统一般使用苹果公司的 iOS和谷歌公司的安卓(Android)。
linux与微软、苹果系统的区别。
Linux(读音为LINN-ux)是一个开放源代码(开源)的操作系统系列,这意味着它们可以被世界各地的任何人修改和分发。这与Windows这样的专有软件不同,后者只能由拥有它的公司进行修改。Linux的优点是它是免费的,且有许多不同的版本可供选择。
据StatCounter Global Stats称 ,Linux用户占全球操作系统的比例不到2%。但是,大多数服务器都运行Linux,因为它相对容易定制。
4、操作系统结构,分类
操作系统中四大部分的不同布局,也就形成了几种整体结构的分野。常见的结构包括:简单结构、层结构、微内核结构、垂直结构、和虚拟机结构。
核的结构可以分为单内核、微内核、超微内核、以及外核等。在众多常用操作系统之中,除了QNX和基于Mach的UNIX等个别系统外,几乎全部采用单内核结构,微内核和超微内核结构主要用于研究性操作系统,还有一些嵌入式系统使用外核。
操作系统的分类没有一个单一的标准,可以根据工作方式分为批处理操作系统、分时操作系统、实时操作系统、网络操作系统和分布式操作系统等;根据架构可以分为单内核操作系统等;根据运行的环境,可以分为桌面操作系统,嵌入式操作系统等;根据指令的长度分为8bit, 16bit, 32bit, 64bit的操作系统。
所谓8位、16位、32位、64位、128位等术语有时指总线宽度,有时指指令宽度(在定长指令集中),而在操作系统理论中主要是指存储器寻址的宽度。
5、计算机硬件
计算机硬件是计算机的重要组成部分,其中包含了 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)
中,覆盖原来的值
进程和线程
这里太深了,就到这,还需要深入研究可以看这篇文章:
https://www.cnblogs.com/cxuanBlog/p/13297199.html
和下面一些资料: