冯诺依曼,操作系统以及进程概念

简介: 冯诺依曼,操作系统以及进程概念

一.冯诺依曼体系结构

计算机大体可以说是由五个硬件组成:存储器,运算器,控制器,输入设备,输出设备

存储器又分为内存(掉电易失)和外存(永久性存储),所谓外存就是除内存以外具有永久性存储能力的存储设备(最常见的是磁盘)

运算器和控制器共同组成了中央处理器,也就是CPU

除此之外电脑中还存在一些输入输出设备,比如:网卡,磁盘等

在冯诺依曼中所说的存储器就是内存

冯诺依曼体系规定了这五个硬件之间是如何进行数据交流的:

通过观察发现,在数据层面上CPU只和内存打交道。

CPU是所有设备中最快的,而输入设备和输出设备作为外设来说是最慢的。如果每次CPU读取/写入数据都要和外设打交道,那么计算机的效率就是以外设作为基准了,因为CPU要等外设将数据拿出/载入,这也极大的浪费了CPU的性能。

越快的东西造价越高,为了不让计算机的价格太高,于是就在CPU和外设之间引入了内存(主存和高速缓存)。

让CPU只和内存打交道,那么整机的效率就由内存决定。内存比CPU要慢,但是比外设要快的多。

对所谓的打交道更详细点说就是:主存从磁盘读取数据并加载到L3高速缓存,L3到L1高速缓存逐级向上加载读取数据,最后将数据加载到寄存器中,CPU再到寄存器中读取数据。

以后聊天别发在吗,因为这个在吗要从你的键盘到你的内存然后还要到你的CPU,最后到你的网卡和显示器,再到我的网卡我的内存我的CPU,最后到我的显示器。太麻烦了,这边建议先叫老公(斜眼笑)

到这里我们可以得到第一个结论:为了提高整机效率,CPU只和内存打交道


我在程序中写了一个printf("hello world\n");于是屏幕上就输出了hello world,是因为我将打印hello world的指令写好点击运行加载到程序以后CPU从内存中读取到这个指令去帮我执行屏幕上才会输出hello world。

也就是说CPU不是天然就有数据的,CPU其实很笨它只会被动的执行我的指令或者操作系统的指令。那么要执行指令,CPU就要认识指令。在CPU内部有它自己的指令集,我写好程序以后这个程序要经过汇编等步骤生成可执行文件本质是将我所写的指令翻译成CPU所认识指令。

二.操作系统(operator system)

操作系统是一个做软硬件资源管理(进程管理,文件管理,内存管理,驱动管理)的软件。对下管理好软硬件(手段),对上提供良好的(稳定的,安全的,高效的)运行环境。


我们首先来理解一下什么是管理,当我们上了大学以后发现平常根本见不到校长,可是校长也能把学校管理好(没倒闭就是管理好了),对于你个人来说,校长怎么知道你给你评三好学生还是要勒令你退学呢?是因为大家的学校都有教务系统,你的一切信息都会在教务系统中实时更新。校长手握教务系统就可以知道你每个学期的成绩,你的综合表现。所以校长知道能知道是否要给你颁奖等。可以从上面的例子中知道,校长能管理好这个学校的根本原因是因为校长能一直拿到这个学校所有学生的数据。

这里可以得到第二个结论:管理的本质就是对数据的管理。

那么我的数据在教务系统中肯定不是以Excel表格的形式呈现的,因为Excel在面临几万项数据时会变得十分的难处理。

虽然我们每个人都是独一无二的,但是我们有共同的属性比如我们都有自己的姓名,家庭住址,电话号码等。也就是说我们的个人数据可以抽象为一个结构体或者类,只要使用特定的数据结构将这些结构体或者类管理起来,就能大大的减少管理的成本。

通过抽象描述和数据结构的组织,最终对我们每个人数据的管理就变成了对结构体或者类的管理,这也就为什么说面向对象是进步的表现。

这里可以得到第三个结论:管理的方法是先描述再组织

我是一个low炮,二十门考试挂了十八门,然后校长决定把我勒令退学。校长根据我的数据做了决策(将我退学),这时就需要有一个人执行校长所做的决策(帮我办理退学手续),这个人就是执行者,而我作为被管理者只能说好吧那我走。

也就是说:在管理者和被管理者之间还有一个执行者,管理者根据数据做决策,执行者更具决策做执行。

电脑是由各种遵循冯诺依曼体系结构的硬件组成的,操作系统是管理硬件的软件,也就是对于硬件来说操作系统就是管理者,那么还需要有一个执行者将管理者做的决策去执行这个决策,最后再收集被管理在这个决策下的数据交给管理者。对于硬件来说,这个执行者就是驱动。

那么到这里我们应该有一个这样的模型:

这就完了吗?肯定没有啊,回想一下我们在学习语言的时候,是不是第一步永远是敲hello world,咔一下这个hello world就打到显示器上了,是因为CPU帮我执行了打印的指令。CPU能执行我的指令不但是因为CPU认识我的指令,更是因为操作系统提供了系统调用的接口。

三.系统调用和库函数

操作系统作为计算机运行的根基,其中的数据是不能被随便更改的。也就是说操作系统并不能相信任何人(就怕群众里面有坏人),但是操作系统又必须要给用户服务。

所以操作系统为了保护自己和服务用户,就将自己封装起来通过给用户提供系统调用的接口来服务用户。为了给我们二次开发提供便利,大佬们就围绕系统调用创造了库函数。这些库函数帮我们去调用了系统调用,所以我们直接咔一个printf("hello world");显示器上就打印了一个hello world。

那么到现在这个结构就能完全展现出来了:

可以看到虽然我们好像在做开发,但其实也是在用户层面做开发。

四.进程

操作系统是管理软硬件资源的软件,经过前面的学习我们已经知道操作系统通过驱动收集的数据对硬件做管理。一个程序想要运行就必须要加载到内存中,而在内存中的程序就是进程,所以操作系统通过对进程的管理来达到管理软件的目的。

1.进程控制块(PCB)

电脑一开机就会有程序被加载到内存中,这些是维护电脑本身所需要的,此外我们还会打开很多程序,也就是说在绝大多数情况下,进程的数量总是超过CPU的。

这就会导致一个CPU往往想要处理多个进程,虽然我们所写的程序本身又不具备进程属性,但一旦加载到内存中成为了进程,操作系统为了管理好进程,就会采用先描述再组织的方法给进程建立进程控制块并用合适的数据结构将这些进程控制块给管理起来。

进程控制块就是进程属性的集合,在Linux下叫做struct task_struct,在Windows下叫PCB。操作系统通过对进程控制块做管理来达到对进程做管理的目的。

总结:struct task_struct内核结构体->内核task_struct对象->将该结构和代码关联

进程=内核数据结构+对应的磁盘代码

2.查看进程

查看进程的指令为ps ajx(查看所有进程)

写一个如下的简单程序:

当我在Linux下执行该程序以后,使用ps ajx|head -1 &&gerp 'proc'就可以查看到进程proc并且可以清楚的知道有关proc的每一项属性代表的是什么意思

那么如果我不想该进程在我的机器上继续运行了就可以使用kill -9+pid杀掉进程

如果在前面的学习过程中你有学过一些退出的骚操作,那么就可能会导致你的部分程序或者工具只是把它放在了后台并没有真正的结束掉这个进程或者工具,这就会导致你的服务器越来越卡。到今天你就可以使用ps ajx查看所有的进程并使用kill -9+ pid杀掉进程


当我的程序加载到内存中后,就成为了进程,这个进程从启动到终止可能中间有很长的一段时间,这就是为什么说进程具有动态属性。

也就是说进程在调度运行的时候,进程就具有动态属性。

3.系统相关的调用

地址是一块空间的唯一标识符,而进程的唯一标识就是id,使用getpid这个系统调用函数就可以拿到相关进程的id

接下来修改一下process.c在其中加入getpid函数

在Linux当中其实存在者一种特殊的目录,即内存级目录,这种目录都是以数字为名存放的都是进程的id

下面来证明一下这种数字文件是代表的是进程的id:

当我的程序在运行的时候我可以找到这个程序对应的id文件

当我杀掉这个程序以后,这个id文件就不存在了

到这里我们可以得到这样一个结论:在Linux下进程可以被当作一个文件来看待

拓展

当一个程序被加载到内存以后,这个程序就成为了进程。那么这个进程是否还要依赖本地的磁盘文件呢?下面我做一个实验

1.运行proc并找到这个程序的进程文件

可以发现这里有一个exe文件,这个exe文件就是pro可执行程序

2.将proc文件删除

当我执行rm proc指令删除掉了本地磁盘种对应的proc文件以后,虽然这个可执行文件开始警告,但是这个进程仍然在运行

所以可以得到这样一个结论,当一个程序被加载到内存以后,理论上这个进程就和对应的文件没关系了

4.fork介绍(并发引入)

fork是一个创建子进程的函数,它有两个返回值,对于子进程来说它的返回值是零,对于父进程来说它的返回值是子进程的pid

根据运行结果可以看到确实有两个proc进程,其中一个的ppid正好是另外一个的pid

而且子进程和父进程共同执行了fork后面的所有语句,也就是说fork后面的所有代码是子进程与父进程共享的

既然fork有两个返回值,那我们就可以通过以fork返回值作为条件来让父子进程分别执行不同的代码,这就是所谓并发。

让子进程休眠一秒,父进程休眠两秒,也就是当子进程打印两句时子进程打印一句

根据结果发现,在同一个程序中同时运行了两个死循环。这在我们以前是想都不敢想的,这就是子进程被创建的作用之一。

此外,我们还可以发现在子进程的父进程也有自己的父进程,并且这个父进程叫做bash。

bash就是Linux系统的内核,在我们启动Linux操作系统时这个bash就被加载了,此后我们所有的指令都是由bash创建的子进程来运行的。我们与bash交互,bash帮我们和操作系统交互。

总结一句话,fork()之后,会有父进程+子进程两个进程在执行后续代码,fork()后续的代码,被父子进程共享,通过返回值不同,让父子进程执行共享代码的一部分,这就是并发式编程

五.总结

1.CPU不直接和外设打交道,只和内存直接打交道,这样可以提高整机效率。

2.操作系统是一个对软硬件资源进行管理的软件。

3.管理的本质是对数据的管理,管理的方法是先描述再组织

4.操作系统不相信任何人,它对外表现为一个整体,通过提供系统调用接口来服务用户。

5.进程=内核数据结构+对应的磁盘代码

6.fork之后的代码由父子进程共享,通过返回值的不同让父子进程各执行共享代码的一部分就叫做并发式编程。

相关文章
|
11天前
|
算法 调度 UED
深入理解操作系统:进程调度与优先级队列
【10月更文挑战第31天】在计算机科学的广阔天地中,操作系统扮演着枢纽的角色,它不仅管理着硬件资源,还为应用程序提供了运行的环境。本文将深入浅出地探讨操作系统的核心概念之一——进程调度,以及如何通过优先级队列来优化资源分配。我们将从基础理论出发,逐步过渡到实际应用,最终以代码示例巩固知识点,旨在为读者揭开操作系统高效管理的神秘面纱。
|
4天前
|
消息中间件 安全 算法
深入理解操作系统:进程管理的艺术
【10月更文挑战第38天】在数字世界的心脏,操作系统扮演着至关重要的角色。它不仅是硬件与软件的桥梁,更是维持计算机运行秩序的守夜人。本文将带你走进操作系统的核心——进程管理,探索它是如何协调和优化资源的使用,确保系统的稳定与高效。我们将从进程的基本概念出发,逐步深入到进程调度、同步与通信,最后探讨进程安全的重要性。通过这篇文章,你将获得对操作系统进程管理的全新认识,为你的计算机科学之旅增添一份深刻的理解。
|
8天前
|
算法 调度 UED
深入理解操作系统:进程管理与调度策略
【10月更文挑战第34天】本文旨在探讨操作系统中至关重要的一环——进程管理及其调度策略。我们将从基础概念入手,逐步揭示进程的生命周期、状态转换以及调度算法的核心原理。文章将通过浅显易懂的语言和具体实例,引导读者理解操作系统如何高效地管理和调度进程,保证系统资源的合理分配和利用。无论你是初学者还是有一定经验的开发者,这篇文章都能为你提供新的视角和深入的理解。
26 3
|
10天前
|
Linux 调度 C语言
深入理解操作系统:进程和线程的管理
【10月更文挑战第32天】本文旨在通过浅显易懂的语言和实际代码示例,带领读者探索操作系统中进程与线程的奥秘。我们将从基础知识出发,逐步深入到它们在操作系统中的实现和管理机制,最终通过实践加深对这一核心概念的理解。无论你是编程新手还是希望复习相关知识的资深开发者,这篇文章都将为你提供有价值的见解。
|
11天前
|
算法 调度 UED
深入理解操作系统的进程调度机制
本文旨在探讨操作系统中至关重要的组成部分之一——进程调度机制。通过详细解析进程调度的概念、目的、类型以及实现方式,本文为读者提供了一个全面了解操作系统如何高效管理进程资源的视角。此外,文章还简要介绍了几种常见的进程调度算法,并分析了它们的优缺点,旨在帮助读者更好地理解操作系统内部的复杂性及其对系统性能的影响。
|
12天前
深入理解操作系统:进程与线程的管理
【10月更文挑战第30天】操作系统是计算机系统的核心,它负责管理计算机硬件资源,为应用程序提供基础服务。本文将深入探讨操作系统中进程和线程的概念、区别以及它们在资源管理中的作用。通过本文的学习,读者将能够更好地理解操作系统的工作原理,并掌握进程和线程的管理技巧。
27 2
|
12天前
|
消息中间件 算法 Linux
深入理解操作系统之进程管理
【10月更文挑战第30天】在数字时代的浪潮中,操作系统作为计算机系统的核心,扮演着至关重要的角色。本文将深入浅出地探讨操作系统中的进程管理机制,从进程的概念入手,逐步解析进程的创建、调度、同步与通信等关键过程,并通过实际代码示例,揭示这些理论在Linux系统中的应用。文章旨在为读者提供一扇窥探操作系统深层工作机制的窗口,同时激发对计算科学深层次理解的兴趣和思考。
|
13天前
|
消息中间件 算法 调度
深入理解操作系统:进程管理与调度策略
【10月更文挑战第29天】本文将带领读者深入探讨操作系统中的核心组件之一——进程,并分析进程管理的重要性。我们将从进程的生命周期入手,逐步揭示进程状态转换、进程调度算法以及优先级调度等关键概念。通过理论讲解与代码演示相结合的方式,本文旨在为读者提供对进程调度机制的全面理解,从而帮助读者更好地掌握操作系统的精髓。
29 1
|
9天前
|
消息中间件 算法 调度
深入理解操作系统:进程管理的艺术
【10月更文挑战第33天】本文旨在揭示操作系统中进程管理的神秘面纱,带领读者从理论到实践,探索进程调度、同步以及通信的精妙之处。通过深入浅出的解释和直观的代码示例,我们将一起踏上这场技术之旅,解锁进程管理的秘密。
15 0
|
11天前
|
算法 Linux 调度
深入理解操作系统之进程调度
【10月更文挑战第31天】在操作系统的心脏跳动中,进程调度扮演着关键角色。本文将深入浅出地探讨进程调度的机制和策略,通过比喻和实例让读者轻松理解这一复杂主题。我们将一起探索不同类型的调度算法,并了解它们如何影响系统性能和用户体验。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇理解操作系统深层工作机制的大门。
21 0

热门文章

最新文章