一.操作系统的定位
操作系统就是搞计算机资源管理的软件统称
1.对上就是要管理好各种硬件设备
2.对下就是要给应用程序提供一个稳定的运行环境
操作系统是软件,硬件和用户之间交换的媒介
二.什么是进程(Process/任务(Task))
下面的这些都是进程
程序是一个可执行文件(静态的),如果双击运行,此时操作系统就会把可执行文件的数据和指令加载到内存中,并让CPU执行这些指令运行起来----进程可以看做程序的一次执行过程(动态的)
并且进程会消耗CPU资源,内存资源,硬盘,网络带宽;
进程是操作系统进行资源分配的基本单位
针对计算机"进程"的管理
1.先描述
使用专门的结构体(PCB在Linux中源码是一个task_struct结构体)进行来记录进程里的各个属性
2.在组织
使用一系列的数据结构(线性表,搜索树),把多个进程进行有效的组织 方便管理进行增删查改操作
举例
当使用双向链表进行组织是(针对Linux来说)
a.查看进程的列表,实际上是遍历这个链表;
b.创建一个进程就是创建一个PCB结构体,并且把这个结构体插入到链表中;
c.删除一个进程就是把这个PCB结构体从链表中删除并释放;
三.进程控制块抽象(PCB Process Control Block)
1.pid进程的标识
同一系统,同一时刻每个进程的pid 一定是不同的;
2.内存指针
表示该进程对应的内存资源(主要存储.exe可执行文件中的数据和指令)
3.文件描述浮表
与硬盘资源有关,
一般来说硬盘是硬件,
应用程序无法直接接触的硬件这一层,
而实际上是操作系统抽象成文件这样的概念,
程序操作的是文件,
文件实际上存储在硬盘上.
操作系统打开一个文件就会产生一个"文件描述符"(类似于文件身份标识且只在进程内部生效)
与此同时使用文件描述浮表(类似于一个数组)就是给文件描述符组织起来;
4.PCB中关于进程调度相关的属性
a.状态
就绪状态:一个进程随时做好了在CPU执行的准备;
阻塞状态/睡眠状态:有时进程还没准备好就被调度到CPU上;
.......
状态可以相互转换
实际上进程在系统的状态还有很多种,就绪状态和阻塞状态是最关键的
b.优先级
系统在给进程进行调度时,会根据优先级的不同,来决定分配的权衡,将系统资源分配给更重要的进程;
举例
比如说你往大型游戏的时候,此时后台的其他应用程序的优先级肯定往后排了;
c.上下文
这些进程轮着上可能一次性运行不完,此时需要保证下次上CPU运行的时候,能从上次运行的时候,继续执行(相当于存档,读档操作)
对于操作系统来说,上下文表示该进程在执行过程中CPU寄存器中对应的数据
d.记账信息
统计每个进程CPU执行力多少次,执行了什么指令,是对于进程调度工作的一个"兜底"
四.CPU的分配 --- 进程调度(Process Scheduling)
每一个进程想要执行里面的指令,完成对应的任务都需要在CPU中进行(假如进程比作演员,CPU就是拍摄场地)
如果一台机器上,进程同一时刻有成百上千个,而CPU只有一个,那怎么办呢?
进程调度
1.并行:同一时刻,两个进程,同时运行运行在两个CPU逻辑核心上;
2.并发:两个进程,在同一个CPU轮着使用(由于CPU切换进程速度非常快,微观上是存续执行的,宏观上来看进程就是同时进行)
操作系统在调度这些进程时可能是并行调度,也可能是并发调度在应用程序层面感知不到(在系统内核中)
由于感知不带是哪一个调度方式,并且在宏观来看,并行与并发是一样的,所以一般用并发代指并行和并发.
五.内存分配 --- 内存管理(Memory Manage)
每一个进程都需要一定的内存资源
在早期的操作系统直接把物理内存分配给了进程,这就带来了一个严重的问题;
一旦某个进程(进程A)内部代码出现问题,内存越界访问了,自己可能没事,却影响到了其它进程(进程B)(死道友不死贫道),这样的设计极大影响了系统的稳定性;
后来为了解决这一问题,操作系统引入了"虚拟地址空间"这样的概念
这样设定之后,每个进程的有效的虚拟地址都是固定的范围
进程使用这样的虚拟地址都需要操作系统转换成物理地址,在这个转换的过程中就可以对虚拟地址是否有效进行效验
当系统检查出非法的地址使用就可以及时的通知这个进程,甚至是挂掉这个进程以免影响其他的进程
由原来的"人工保证" 变为 "系统的自动检测" ,每个进程就影响不到其它进程,大大提高了系统的稳定性;
六.进程间的通信(Inter Process Communication)
通过虚拟地址空间,将进程隔离开了,但有些时候需要进程直接产生点联系
进程间通信方法:
- 管道
- 共享内存
- 文件
- 网络
- 信号量
- 信号
本质上都是找到一个共同的区域(多个进程都能访问到),借助公共区域完成数据的交换;