文章目录

一、冯诺依曼体系结构
我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系。
总体来讲:计算机可以分为==输入设备、输出设备、存储器、运算器&&控制器==
我们知道,CPU的速度是最快的,里面配有寄存器也是最快的,内存是较快的,而外设是较慢的:
CPU只能被动接收别人的指令,别人的数据,所以CPU要去识别别人的指令(制造时内置自己的指令集)才能执行别人的指令
内存存在的意义在于:👇
而我们所说到的IO(输入输出既input和output)就是从内存的角度上看,把数据从输入设备存入内存的过程叫做input,把内存中的数据输出到输出设备的过程叫做output,这就是IO的过程。
对于冯诺依曼体系,我们应该注意:
所以程序的运行必须要加载到内存,CPU执行的代码访问数据,只能从内存中读取(这也是体系结构规定的)。
二、操作系统(OS)
- 是什么
操作系统是一个进行软硬件资源管理的软件,操作系统内有进程管理,文件系统,内存管理,驱动管理
- 为什么
操作系统对下通过合理的管理软硬件资源,对上为用户提供稳定的、高效的、安全的、的执行环境
- 怎么办
管理的本质是对数据做管理,操作系统并不是直接对计算机中的各种硬件进行决策管理,而是通过数据进行分析,最终做出决策,再由驱动执行,从而达到管理的效果
- 计算机的体系结构图
所有的管理,本质是对数据做管理,管理的方法是先描述在组织
计算机管理硬件
- 描述起来,用struct结构体
- 组织起来,用链表或其他高效的数据结构
三、系统调用和库函数
这对应着用计算机体系结构图中的户操作接口和system call,我们或者说用户不是直接和操作系统进行操作交流的,需要通过调用各种接口间接地进行交流
四、进程
4.1概念
课本概念📝:一个运行起来(加载到内存)的程序叫进程,在内存中的程序叫进程
内核观点📝:担当分配系统资源(CPU时间,内存)的实体
4.2描述进程-PCB
- PCB
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block), Linux操作系统下的PCB是: task_struct
- 程序和进程
程序的本质是放在磁盘上的可执行文件(.exe文件),就是一个文件,根据冯诺依曼体系,软件运行要加载到内存中,而进程则是将程序加载到内存当中,并且由操作系统进行管理,生成一个描述自身性质的数据结构(PCB),由内核数据结构和进程对应的磁盘代码两者共同组成“进程”
- task_struct
task_struct-PCB的一种,在Linux中描述进程的结构体叫做task_struct。task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息 。
- task_ struct内容分类
4.3查看进程
说了这么多进程,我们总得见一见进程是啥样的把:
首先,创建文件(myproc.c和Makefile):
文件内容:
make一下,生成可执行程序,开始执行:
接下来就是查看进程了:
同时,我们可以杀掉(kill)进程,当然ctrl+c也可以直接结束掉:
进程在运行的时候本质是在读取进程内部的代码,内部在执行,从启动到终止中间可能会有一段很长的时间,这个进程就具备了动态属性。
也就是说,进程在调度运行的时候,进程就具有动态属性
以上就是我们对于进程简单的查看。
4.4与系统相关的系统调用
需要用到getpid()
获取进程PID需要两个头文件,调用响相应函数,最后的返回值就是进程的PID
下面我们对myproc.c进行修改:
执行:
此外,我们还可以了解一下另一种查看进程的方式简单学习一下。
在Linux中proc是内存级目录
数字开头就是进程的pid,一个进程也可以当做文件来看待
如果我们结束进程,自然就找不到了:
我们重新执行,进入:
4.5系统调用获取进程标示符
进程id(PID)
父进程id(PPID)
命令行上启动的进程,一般它的父进程没有特殊情况的话,都是bash
4.5fork初识(并发引入)
- fork的第一个阶段使用
创建子进程
- fork的另一阶段使用
我们需要看fork的返回值:
(所以对于结果我们很好理解,返回成功时,会给父进程返回子进程的pid,子进程会返回0)。但是,这里居然一个变量id居然会有两个返回值,这里在以前是想都不敢想的,后面我们在展开这个问题。我们根据这个返回结果写代码:
多进程:
我们可以看到,两个while循环都执行起来了,这也证明了实际上参与while循环的有两个进程!并且它们是父子进程,即父子关系。
这也说明了,在fork之后,又创建了一个进程,两个进程分别在两个执行流中,因此可以分别执行if 和 else if,也可以分别进入while循环!
总结一句话,fork()之后,会有父进程+子进程两个进程在执行后续代码,fork()后续的代码,被父子进程共享,通过返回值不同,让父子进程执行共享代码的一部分,这就是并发式编程。