操作系统(Operator System)
操作系统(Operating System)
概念
一个基本的程序集合,称为操作系统(OS)
操作系统是一款用于管理软硬件的软件,其本身也是一款软件。
操作系统包括:
- 内核(进程管理,内存管理,文件操作,驱动管理)
- 其他程序(例如函数库、shell程序等等)
狭义上的操作系统指的是操作系统的核心,即内核。但是,Linux的内核直接交给用户是无法使用的。为了能在Linux系统上进行开发,需要提供函数库、shell程序、图形界面等。因此,从广义上来说,操作系统包括内核以及安装在其上的外壳程序(shell)、glibc、原生库和预装系统级软件。
扩展
安卓的底层使用的是Linux内核。那么安卓用了Linux内核的什么呢?手机可以看作小型计算机,具备内存、CPU、存储、显示和输入输出设备,因此手机实际上也是一个小型的冯·诺伊曼体系结构计算机。手机上的内存、文件、软硬件、任务和APP都需要由操作系统管理。操作系统正是负责此类管理工作,因此会将操作系统内核移植到手机上。手机的输入输出设备是整合在一起的,屏幕同时作为输入和输出设备。Windows有Windows的界面,Linux有Linux的界面,手机也需要自己的界面。因此,基于Linux内核,通过改变其外壳,设计一个专门的外壳程序,这个外壳程序就称为安卓。安卓会提供基本的图形界面以及自己的库,供开发者调用,以创建不同APP在安卓系统下的界面,从而形成了基于安卓的开发(Linux操作系统提供了glibc这一C语言标准库,我们可以基于glibc在Linux上开发,同理也可以在安卓上开发)。有人说安卓的底层是Linux,意思是安卓系统在最核心的部分使用了Linux内核。Windows系统也是类似的道理。
设计OS的目的

计算机结构如上图所示。底层硬件在逻辑上是按照冯·诺伊曼体系结构组织的,每个硬件设备都需要有对应的驱动程序,例如网卡有网卡驱动,硬盘有硬盘驱动等。在硬件层面,每种硬件的访问模式各不相同,比如读取键盘数据、读取鼠标数据、读取网卡数据、读取磁盘数据,访问不同设备需要个性化的读取方式。因此,访问不同硬件需要调用不同的驱动程序,这是一个基本事实。
(案例:电脑刚开机时没有连接鼠标,之后我们物理上连接鼠标,插上后动几下发现鼠标不动,大概等上一两秒,电脑右下角弹出一个小窗口提示“某某驱动安装成功”,这时鼠标就可以使用了。)
换言之,硬件必须在驱动程序安装成功后才能被访问。在驱动程序之上是操作系统。
OS存在的意义是什么?
1)对下:OS与硬件交互,需要向下进行软硬件资源的管理
我们要打游戏,结果操作系统告诉它管不住显示器,显示器一下黑一下白的,管不了,所以操作系统必须保证每种硬件(硬件是健康的)需要把硬件的工作模式体现到用户层面上,我们对一个设备进行更改,操作系统都需要把这些设备统一管理起来
但是操作系统把硬件管理起来并不是目的,而是手段
2)对上:OS为用户程序(应用程序)提供一个良好的执行环境
我们打游戏不可能是10分钟一黑屏,半小时一重启,用户是无法接受的,所以操作系统能不能把底层的硬件管理好,不要让它们老是出错,要给上层提供一个良好的工作环境
所以操作系统存在的目的是给用户提供服务的
OS是需要对底层的硬件包括未来的软件进行管理,以此为手段为上层用户提供一个良好的稳定的环境
1、软硬件体系层状结构—从硬件到用户
高内聚、底耦合
高内聚:相同功能、相同逻辑的代码数据放在同一层的内部,比如操作系统内都是操作系统的数据,驱动程序内就是驱动程序自己的代码数据,硬件就是纯硬件底耦合:层跟层之间,本身只使用一些接口的方式进行互相调用,在数据的逻辑层面上没有强耦合
这样我们之后修改计算机体系结构中的一个,只需要在对应层级里修改,不会影响到其他的层级,我们改操作系统,驱动和硬件都不需要修改,我们修改硬件,操作系统和驱动程序也不要修改(这样做的目的是为了之后代码的
可维护性)就和我们写C语言代码,我们最开始写代码都是把代码全部塞到main函数,我们此时的代码难以维护,没有高内聚、底耦合,但我们学习了函数,我们把main的各个方法封装到函数里,用函数调用,此时main函数是顶层是调用层,而函数方法为方法层,此时的代码就是可维护的,有问题就到对应的函数找问题
我们的C++的面向对象三大特性
封装继承多态的继承多态,这里的继承的基类子类这样的继承关系不久是这样的层状结构吗?基类一层,子类一层,这样的层状结构是软件很常见的结构
硬件设备是可替换掉,我们的硬件设备可以是不同厂商提供的,这恰恰说明了,我们硬件的设计,本身就满足了高内聚、底耦合的特性,什么硬件坏了换什么硬件即整个计算机世界就是
高内聚、低耦合的!
2、访问操作系统,必须使用系统调用 – 其实就是函数,只不过是系统提供的
操作系统不允许用户直接访问内存,进程,文件,和驱动,操作系统要求必须使用它自己提供的C语言封装的接口来访问底层,这个接口叫做系统调用,理解操作系统才可以更好的使用系统调用
3、我们的程序,只要你判断它访问了硬件,那么它必须贯穿整个软硬件体系结构!
我们向显示器上打印数据,本质是把数据写到了硬件!显示器!不可能是我们写的C语言程序直接将数据写到硬件上,计算机体系是层状的,我做开发,用到C标准库的方法,最终确实达到了把数据写到硬件的结果,但我们是不可能直接绕过操作系统,直接访问硬件的,不可能!所以这个printf库函数的底层会被封装到系统调用,然后通过操作系统对驱动进行访问,访问对应的驱动,然后才能把数据交到硬件上,所以我们之前学习的很多操作,如scanf,printf 这些IO操作有关的,全都必须贯穿操作系统
4、库可能在底层封装好了系统调用
我们讲到数据访问硬件要通过系统调用等一系列贯穿操作系统的流程才可能,但是我们以前学习从来没有看到过系统调用呀?就printf来说,我们平时都是直接使用printf这样的函数接口,但是我们并没有去了解其底层!其实printf底层是封装了一系列访问系统调用的接口以及系统访问IO的接口,我们平时使用系统调用太麻烦了,所以有人帮我们封装了这个操作,形成了一个库,我们之前所使用过的C语言标准库,stdio.h 、iostream、STL模板库都是C标准提供的,
库本身给系统调用做了封装,所以用户在上层做硬件访问时只需要使用上层的代码就可以,所以我们用户平时的开发场景是在用户层中进行的所以在用户层,指令操作、开发操作、管理操作的任务都会通过应用程序转化为系统调用接口,访问操作系统
核心功能
理解操作系统OS
学习事务的三要素:是什么、为什么、怎么做。我们首先会到“是什么”阶段,好好理解操作系统。
操作系统在整个软硬件层次中,处于一个承上启下的位置。在整个计算机软硬件架构中,操作系统的定位是:一款纯粹的“管理”软件。
如何理解“管理”
管理的例子: 学生、辅导员、校长
学生是被管理者、校长是管理者,
其实人在日常生活中做的事情无非就两件,一个是决策,二是执行,我们个人平时是决策和执行一起的
而在一个管理体系中,管理者最大的能力是有决策权,而真正的执行者往往是体系的中间层,辅导员没有决策权,只能执行
将这个关系映射到软硬件体系的下三层中,操作系统、驱动程序、底层硬件,而操作系统相当于校长,底层硬件相当于学生,驱动程序相当于辅导员所以是如何管理的呢?
1)要管理,管理者和被管理者可以不需要见面
2)管理者和被管理者,怎么管理呢?根据“数据”进行管理管理者所需要的是被管理者的数据,即使管理者去见被管理者,其目的也不是见面,而是获取被管理者的数据(上课考勤情况,学分绩点如何)管理者是通过被管理者的数据进行一系列的决策,即管理者和被管理者见面接触并不是管理的必要条件,见面的本质是获取你身上的相关数据,根据你的“数据”进行管理
所以我们这个世界上的管理本质是通过数据进行管理的3)不需要见面,如何得到数据?由中间层(辅导员,经理)获取!
综上,操作系统管理硬件,并不需要与硬件打交道,操作系统管理硬件是通过数据进行管理的,而要管理数据,是从驱动程序获取硬件数据
(系统刚开启的第一个决策是让驱动程序去获取底层硬件的数据)
管理者对数据也是要有限制有要求的,不能随意的获取吧,要有目的性
校长1.0
校长在一个excel表格中写了一系列的要求(姓名、班级、年龄…),让辅导员去找同学们收集这些信息完成要求,最后校长拿到完整数据的表格,为了方便管理,在搞城云管理,辅导员一在表格中修改数据,校长就可以立马知道了,所以校长的管理工作从管理学生到管理学生的数据,校长每天都过一遍数据,并下达一系列的决策(XXX数学成绩好,让辅导员去推荐他去参加数学竞赛,并给他一系列备赛资料;XXX挂科过多,让辅导员去通知他被退学了)并对管理的数据进行修改(被退学的人的信息被删除掉,之后有新同学入学,也需要录入这些同学的信息)
综上,我们可以知道,校长
管理学生转化成了对excel表格的数据的管理但是有个问题!校长每天都要过一遍这个数据,如果这个数据太大了,校长每天看数据都会累的够呛!根本管理不过来!但是校长在管理数据的时候,要么是找学习成绩最好的,要么是找成绩最差的,要么是找某个特定职位的,校长管理数据的本质还是
增删查改,但随着人数的增多,增删查改对于校长负担越来越大了,所以来讲讲校长2.0 — 前身为顶级程序员校长2.0 — 程序员!
校长2.0在想,我们能不能不用excel表格来管理学生数据呢?可以让计算机来管理数据吗?我们可以发现,excel表格中一行的信息,是这个学生的相关属性,不同行的同学的属性完全一样,只是数值不一样,想通过代码来处理学生的管理工作,这首先要把一个学生管理起来,在一个软件上,如何将学生不同的属性集合到一起,在数据上用这个集合代表同学,C语言中,使用数据类型
结构体,在结构体中定义姓名、性别、年龄、籍贯…struct stu { //姓名 //年龄 //性别 //籍贯 //..... }在excel表格中,每行数据都是一个学生的对于属性值,而我们上面的结构体的定义,不就相当于excel表格表头的那一行属性吗!要记录任何一个同学的信息,通过结构体定义的类型定义变量
struct stu ZhangSan = {...}学生姓名以此类推下去,这代表这,我们学校有10W个人,我们就可以用这样的结构体来定义10W个变量来代表这些同学,这里每个变量保存的就是对应学生的基本信息了,这里每个学生保存的基本信息也对应excel的一行,在excel表格中有10W行数据,而在C语言中有10W个变量
对于校长来说,管理学生用结构体来管,但是现在的学生变量是一个一个独立的!校长要找数学成绩最好的,不可能对10W个变量一个一个穷举,访问里面的数学成绩,太麻烦了,校长这个时候就在想,能不能直接在学生结构体中再加一个学生结构体指针。
(设置一个学生结构体指针,作为进入数据的接口,第一个同学入学,就为他开辟一个结构体变量,这个指针就指向它,随后又有同学入学,又开辟了一个结构体变量,让他们输入数据,但是这两个变量之间是独立,要如何将他们联系起来,使用第一个节点的结构体指针指向下一个节点,以此达到连接,以此类推,形成了一个学生链表)
以前的excel表格相当于顺序表,但是操作都是人为操作的,而我们有了链表,事情就有了变化,我们校长日常的决策(找最高的人、成绩最好的人)就转化为计算机中链表的遍历,校长日常的决策中找C语言成绩最好的同学去参加比赛,在C语言中就是根据学生C语言成绩属性来遍历学生链表,以此找到成绩最好的人,其他决策同理!
我们可以发现,日常的校长管理学生的工作(现实人做的事情) -> 对链表的增删查改!(计算机完成)
这里不一定是链表也可以是其他数据结构
综上,校长对学校的管理就转化成了我们不需要再对excel进行管理,可以让系统管理学生,即链表结构来实现增删查改,所以现在,有了新学生,直接开辟节点输入数据,再接入链表即可
校长管理转化为链表的操作,实际是做了校长日常管理建模的过程这个建模的过程,高度精简就是
“先描述 再组织”
这里校长管理学生,先描述起来,把同学(管理对象)的所有属性封装到结构体中,然后未来有学生(管理对象)出现,就用该结构体来定义变量申请节点(定义张三、李四的结构体变量),最后在把节点组织起来,使用恰当的数据结构来粗存节点所有
先描述,再组织可以完成对现实世界任何的管理情景进行建模!
回到计算机软硬件体系结构中,操作系统是如何管理下层设备的呢?底层硬件有名字,有状态,等属性,操作系统是管理者,那么操作系统可以在内部先描述再组织,将各种硬件的一系列属性通过结构体struct device 的方式封装到一起定义一个类,类内包含硬件的各种属性,操作系统会在内部构建各种硬件的结构体对象,将这些对象都管理起来,即操作系统对硬件的管理,转化为对硬件数据的增删查改
进程的管理也是同理,先描述再组织,在操作系统内部构建进程结构体,封装其属性,在实现一系列要管理的对象,将对象用恰当的数据结构储存起来,转变为在数据结构内的数据的增删查改
先描述,再组织思想非常重要,这也是C++提供类和STL的原因,也不仅仅是C++,其他编程语言也提供类的概念和集成类的概念,这是因为,类是解决先描述的问题,STL是容器,容器即是数据结构,是解决再组织的问题。这也是面向对象为主流的原因,这也是这个世界的的特点,是先描述再组织的世界,这也是为什么要学习数据结构,是对现实生活中所有管理的模型全都转化为结构化数据,翻译成数据结构才能让计算机看懂
描述被管理对象
组织被管理对象
13集20分钟以前谈了操作系统相关问题
理解系统调用 和 库函数(用户操作接口)
操作系统要向上提供对应的服务
什么是服务?我们在printf的时候本质是把printf字符串写到屏幕这个硬件上,而scanf读入的时候,是把键盘硬件的数据读入到软件程序当中,这样的过程必然要有操作系统的参与,操作系统需要为我们提供访问硬件的能力,这个提供的能力就是为我们提供的服务!
操作系统,不相信任何用户或者人
感觉有点矛盾,操作系统既要服务我们又不相信我们,我们用一个例子来方便理解
银行!
银行要为用户提供服务!银行要为用户办理一系列的业务,存款、贷款、理财等。
银行是不相信任何用户或者人的!银行是不可能允许我们去访问他们的金库的,银行要保护客户的财产安全。银行为了防止非授权者访问金库又要为用户提供服务,银行会在最外层设置业务窗口,我们在银行窗口办理业务,通过窗口把身份证、户口本递进去,银行工作人员确认身份信息后,再从银行金库中把你存的钱按你的要求取出来完成业务。
所以操作系统要为用户提供服务又不相信用户,操作系统要把自己也变成银行,操作系统把自己封装起来,不让用户访问操作系统任何的细节,但也要为用户提供一个办理业务的窗口——系统调用
系统调用本质上是操作系统给我们提供的函数调用,比如 **fork、waitpid 、socket**这些系统调用,所有用户访问操作系统,获取操作系统内部的数据,设置自己的信息,全部都是通过函数调用实现的。
Linux/Windows/macos -->操作系统基本上是用C语言写的 --> 系统调用一般也是C语言函数
函数有输入参数和返回值,输入参数是用户给操作系统的,而返回值是操作系统返回给用户的
所有系统调用本质是操作系统和用户之间进行某种**
数据交互**这样的交互只是通过数据,耦合度也低了
那我们为什么没有见过系统调用呢?
在银行的工作中,用户通过业务窗口向银行申请业务,但是大家也是知道的,银行业务办理起来相对麻烦,如果有有些老年人来办理业务怎么办?假设我是一个90岁的老大爷,看不清也不认识字,想把2K存到银行中,这时候怎么办呢?一般好些的银行会有大堂经理在窗口外侧为协助用户办理业务,有了大堂经理这位大爷办理业务就方便多了。
同理!让计算机小白直接访问系统调用的接口,成本很高,需要学会很多知识才能理解其中的意义,所有这里操作系统会给开发者提供一些库、给操作者提供外壳、指令,这些东西的底层无一例外都是直接或者间接的访问系统调用,但是这些是别人做好了,只要我们灵活使用这些工具也能访问系统调用,即我们当前就是什么例子的大爷,这些库、外壳、指令相当于大堂经理
我们没有遇到、没感觉到系统调用是因为为操作系统封装的一批人帮我们为软件进行封装了,使用用户是基于别人的设置、封装进行开发的
- 在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
- 系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成
库,有了库,就很有利于更上层用户或者开发者进行二次开发。
使用库函数和系统调用的上下层的关系!
所以对库文件,库文件的函有没有在底层调用系统调用,是可以直接到这个函数最终有没有调用硬件,输入输出,调用网络等
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)