在平时的生活中,我们几乎时时刻刻都在使用操作系统,只是大部分时间你都意识不到它的存在。比如你买了一部手机或者一台平板电脑,立马就能上手使用,这是因为它们里面都预先安装了操作系统。
所以啊,哪有什么岁月静好,只不过有人替你负重前行。而操作系统就扮演了这样一个负重前行的角色。那操作系统到底在背后默默地做了哪些事情,才能让我们轻松地使用这些电子设备呢?要想回答这个问题,我们需要把眼光放回到自己攒电脑的那个时代。
电脑组装好就能直接用吗?
那时候买电脑,经常是这样一个情景:三五个哥们儿一起来到电脑城,呼啦呼啦采购了一大堆硬件,有密密麻麻都是针脚的CPU;有铺满各种复杂电路的一块板子,也就是主板;还需要买块显卡,用来连接显示器;还需要买个网卡,里面可以插网线;还要买块硬盘,将来用来存放文件;然后还需要一大堆线,将这些设备和主板连接起来;最终再来一个鼠标,一个键盘,还有一个显示器。设备差不多啦,准备开整!
好不容易组装完这一大堆硬件,还是不能直接用,你还需要安装一个操作系统。安装操作系统也是一件非常复杂的事,一点儿也不亚于把刚才那堆东西组装起来。这个安装过程可能会涉及十几个步骤、几十项配置。每一步骤配置完了,点击下一步,会出现个进度条。伴随着一堆难以理解的描述,最终安装步骤到达百分之百,才出现你熟悉的那个界面。
我这么说起来好像很容易,但是要把这事儿讲清楚估计得用一个专栏。这个复杂程度,咱们父母估计是上不了手了。所以,那个时候,能把这套东西都组装起来,是一件很拉风的事情。很多 IT 男甚至因为这项绝技“泡”到了妹子。
当操作系统安装完毕的时候,我妈通常会要求我一定要装一个 QQ。看到妈妈在你装好的操作系统前愉快地和她的朋友聊天,这时候,经历过以上过程的你,多少应该能感受到操作系统的厉害了。
操作系统究竟是如何把这么多套复杂的东西管理起来,从而弄出来一个简单到父母都会用的东西呢?
很多事情就怕细想。不知道你有没有产生过这些疑问:
桌面上的图标到底是啥?凭啥我在鼠标上一双击,就会出来一个美丽的画面?这都是从哪里跑出来的?
凭什么我在键盘上噼里啪啦地敲,某个位置就会显示我想要的那些字符?
电脑怎么知道我鼠标点击的是这个地方,又是怎么知道我要输入的是这个地方?
我在键盘上点“a”,是谁在显示器上画出“a”这个图像呢?
为什么我一回车,这些字符就发到遥远的另外一台机器上去了?
对于普通用户来讲,其实只要会用就行了,但是咱们作为专业人士,要深入探究一下背后的答案。你别小看“双击鼠标打开聊天软件”这样一个简单的操作,它几乎涵盖了操作系统的所有功能。我们就从这个熟悉的操作,来认识陌生的操作系统。
操作系统其实就像一个软件外包公司,其内核就相当于这家外包公司的老板。所以接下来的整个课程中,请你将自己的角色切换成这家软件外包公司的老板,设身处地地去理解操作系统是如何协调各种资源,帮客户做成事情的。
想要学好咱们这门课,你要牢牢记住这段话,把这个概念牢牢扎根在心里,我之后的讲解都会基于此,帮你理解、记忆那些难搞的概念和原理。
同时,为了防止你混淆,我这里先强调一下。今后我所说的“用户”,都是指操作系统的用户,“客户”则是指外包公司的客户,这两者是对应的。
“双击 QQ”这个过程,都需要用到哪些硬件?
好,现在用户开始对着屏幕上的 QQ 图标双击鼠标了。
鼠标和键盘是计算机的输入设备。大部分的普通用户想要告诉计算机应该做什么,都是通过这两个设备。例如,用户移动了一下鼠标,鼠标就会通过鼠标线给电脑发消息,告知电脑,鼠标向某个方向移动了多少距离。
如果是一家外包公司,怎么才能知道客户的需求呢?你需要配备销售、售前等角色,专门负责和客户对接,把客户需求拿回来,我们把这些人统称为客户对接员。你可以跟客户说,有什么事儿都找对接员。
屏幕,也就是显示器,是计算机的输出设备,将计算机处理用户请求后的结果展现给客户,要不然用户无法知道自己的请求是不是到达并且执行了。
显示器上面显示的东西是由显卡控制的。无论是显示器还是显卡,这里都有个“坐标”的概念,也就是说,什么图像在哪个坐标,都是定义好了才画上去的。本来在某个坐标画了一个鼠标箭头,当接到鼠标移动的事件之后,你应该按相同的方向,按照一定的比例(鼠标灵敏度),在屏幕的某个坐标再画一个鼠标箭头。
作为外包公司,当客户给你提了需求,不管你做还是不做,最终做成什么样,你都需要给客户反馈,所以你要配备交付人员,将做好的需求展示给他们看。
在操作系统中,输入设备驱动其实就是客户对接员。有时候新插上一个鼠标的时候,会弹出一个通知你安装驱动,这就是操作系统这家外包公司给你配备对接人员呢。当客户告诉对接员需求的时候,对于操作系统来讲,输入设备会发送一个中断。这个概念很好理解。客户肯定希望外包公司把正在做的事情都停下来服务它。所以,这个时候客户发送的需求就被称为中断事件(Interrupt Event)。
显卡会有显卡驱动,在操作系统中称为输出设备驱动,也就是上面说的交付人员。
从点击 QQ 图标,看操作系统全貌
有了客户对接员和交付人员,外包公司就可以处理用户“在桌面上点击 QQ 图标”的事件了。
首先,鼠标双击会触发一个中断,这相当于客户告知客户对接员“有了新需求,需要处理一下”。你会事先把处理这种问题的方法教给客户对接员。在操作系统里面就是调用中断处理函数。操作系统发现双击的是一个图标,就明白了用户的原始诉求,准备运行 QQ 和别人聊天。
你会发现,运行 QQ 是一件大事,因为将来的一段时间,用户要一直和 QQ 进行交互。这就相当于你们公司接了一个大单,而不是处理零星的客户需求,这个时候应该单独立项。一旦立了项,以后与这个项目有关的事情,都由这个项目组来处理。
立项可不能随便立,一定要有一个项目执行计划书,说明这个项目打算怎么做,一步一步如何执行,遇到什么情况应该怎么办等等。换句话说,对 QQ 这个程序来说,它能做哪些事情,每个事情怎么做,先做啥后做啥,都已经作为程序逻辑写在程序里面,并且编译成为二进制了。这个程序就相当于项目执行计划书。
电脑上的程序有很多,什么有道云笔记的程序、Word 程序等等,它们都以二进制文件的形式保存在硬盘上。硬盘是个物理设备,要按照规定格式化成为文件系统,才能存放这些程序。文件系统需要一个系统进行统一管理,称为文件管理子系统(File Management Subsystem)。
对于你们公司,项目立得多了,项目执行计划书也会很多,同样需要有个统一保存文件的档案库,而且需要有序地管理起来。
当你从资料库里面拿到这个项目执行计划书,接下来就需要开始执行这个项目了。项目执行计划书是静态的,项目的执行是动态的。
同理,当操作系统拿到 QQ 的二进制执行文件的时候,就可以运行这个文件了。QQ 的二进制文件是静态的,称为程序(Program),而运行起来的 QQ,是不断进行的,称为进程(Process)。
说了这么多,怎样才能立项呢?你会发现,一个项目要想顺畅进行,需要用到公司的各种资源,比如说盖个公章、开个证明、申请个会议室、打印个材料等等。这里有个两难的权衡,一方面,资源毕竟是有限的,甚至是涉及机密的,不能由项目组滥取滥用;另一方面,就是效率,咱是一个私营企业,保证项目申请资源的时候只跑一次,这样才能比较高效。
为了平衡这一点,一方面涉及核心权限的资源,还是应该被公司严格把控,审批了才能用;另外一方面,为了提高效率,最好有个统一的办事大厅,明文列出提供哪些服务,谁需要可以来申请,然后就会有回应。
在操作系统中,也有同样的问题,例如多个进程都要往打印机上打印文件,如果随便乱打印进程,就会出现同样一张纸,第一行是 A 进程输出的文字,第二行是 B 进程输出的文字,全乱套了。所以,打印机的直接操作是放在操作系统内核里面的,进程不能随便操作。但是操作系统也提供一个办事大厅,也就是系统调用(System Call)。
系统调用也能列出来提供哪些接口可以调用,进程有需要的时候就可以去调用。这其中,立项是办事大厅提供的关键服务之一。同样,任何一个程序要想运行起来,就需要调用系统调用,创建进程。
一旦项目正式立项,就要开始执行,就要成立项目组,将开发人员分配到这个项目组,按照项目执行计划书一步一步执行。为了管理这个项目,我们还需要一个项目经理、一套项目管理流程、一个项目管理系统,例如程序员比较熟悉的 Jira。如果项目多,可能一个开发人员需要同时执行多个项目,这就要考验项目经理的调度能力了。
在操作系统中,进程的执行也需要分配 CPU 进行执行,也就是按照程序里面的二进制代码一行一行地执行。于是,为了管理进程,我们还需要一个进程管理子系统(Process Management Subsystem)。如果运行的进程很多,则一个 CPU 会并发运行多个进程,也就需要 CPU 的调度能力了。
每个项目都有自己的私密资料,这些资料不能被其他项目组看到。这些资料主要是项目在执行的过程中,产生的很多中间成果,例如架构图、流程图。
执行过程中,难免要在白板上或者本子上写写画画,如果不同项目的办公空间不隔离,一方面,项目的私密性不能得到保证,A 项目的细节,B 项目也能看到;另一方面,项目之间会相互干扰,A 项目组的人刚在白板上画了一个架构图,出去上个厕所,结果 B 项目组的人就给擦了。
如果把不同的项目组分配到不同的会议室,就解决了这个问题。当然会议室是有限的,需要有人管理和分配,并且需要一个会议室管理系统。
在操作系统中,不同的进程有不同的内存空间,但是整个电脑内存就这么点儿,所以需要统一的管理和分配,这就需要内存管理子系统(Memory Management Subsystem)。
如果想直观地了解 QQ 如何使用 CPU 和内存,可以打开任务管理器,你就能看到 QQ 这个进程耗费的 CPU 和内存。
项目执行的时候,有了一定的成果,就要给客户演示。例如客户说要做个应用,我们做出来了要给客户看看,如果客户说哪里需要改,可以根据客户的需求再改,这就需要交付人员了。
QQ 启动之后,有一部分代码会在显示器上画一个对话框,并且将键盘的焦点放在了输入框里面。CPU 根据这些指令,就会告知显卡驱动程序,将这个对话框画出来。
于是使用 QQ 的用户就会很开心地发现,他能和别人开始聊天了。
当用户通过键盘噼里啪啦打字的时候,键盘也是输入设备,也会触发中断,通知相应的输入设备驱动程序。
我们假设用户输入了一个“a”。这就像客户提出了新的需求给客户对接员。客户对接员收到需求后,因为是对接这个项目的,因而就回来报告,客户提新需求了,项目组需要处理一下。项目执行计划书里面一般都会有当遇到何种需求应该怎么做的规定,项目组就按这个规定做了,然后让交付人员再去客户那里演示就行了。
对于 QQ 来讲,由于键盘闪啊闪的焦点在 QQ 这个对话框上,因而操作系统知道,这个事件是给这个进程的。QQ 的代码里面肯定有遇到这种事件如何处理的代码,就会执行。一般是记录下客户的输入,并且告知显卡驱动程序,在那个地方画一个“a”。显卡画完了,客户看到了,就觉得自己的输入成功了。
当用户输入完毕之后,回车一下,还是会通过键盘驱动程序告诉操作系统,操作系统还是会找到 QQ,QQ 会将用户的输入发送到网络上。QQ 进程是不能直接发送网络包的,需要调用系统调用,内核使用网卡驱动程序进行发送。
这就像客户对接员接到一个需求,但是这个需求需要和其他公司沟通,这就需要依靠公司的对外合作部,对外合作部在办事大厅有专门的窗口,非常方便。
总结时刻
到这里,一个外包公司大部分的职能部门都凑齐了。你可以对应着下图的操作系统内核体系结构,回顾一下它们是如何组成一家公司的。
QQ 的运行过程,只是一个简单的比喻。在后面的章节中,我会展开讲述每个部分是怎么工作的,最后我会再将这个过程串起来,这样你就能了解操作系统的全貌了。
操作系统内核体系结构图
课堂练习
学习 Linux,看代码是必须的。你可以找到最新版本的 Linux 代码,在里面找找,这几个子系统的代码都在哪里。
欢迎留言和我分享你的思考和疑问,也欢迎你把今天的内容分享给你的朋友,和他一起学习、进步。