文章目录
- 前言
- 1. 什么是操作系统
- 2. 操作系统的定位
- 3. 进程管理
- 3.1 什么是进程/任务 (Process/Task)
- 3.2 进程管理怎么做的
- 3.3 进程控制块抽象PCB (Process Control Block)
- 3.3.1 进程调度属性
- 4. 内存分配 ---- 内存管理 (Memory Manage)
- 5. 进程间通信 (Inter Process Communication)
- 总结
前言
本文主要讲的是操作系统的一些核心概念, 主要讲解进程管理和进程调度的问题, 当然学习完本篇并不会让你能从零打造一个操作系统, 而只是让读者有了对操作系统核心概念的基本认识.
关注收藏, 开始学习吧🧐
1. 什么是操作系统
操作系统是一组做计算机资源管理的软件的统称, 其本质上也是一个软件, 目前常见的操作系统有: Windows系列, Unix系列, Linux系列, OSX系列, Android系列, iOS系列, 鸿蒙等等.
2. 操作系统的定位
操作系统, 对下要管理好各种硬件设备, 对上要给各个软件提供稳定的运行环境.
比如某个软件程序, 想要操作某个硬件设备, 此时就需要通过操作系统来完成.
操作系统有两个基本功能:
- 防止硬件被时空的应用程序滥用.
- 向应用程序提供简单一致的机制来控制复杂而又通常大相径庭的低级硬件设备.
操作系统本身是一个很大的话题, 是一个十分复杂的软件, 其功能是非常多的, 其中有一个对于我们来讲十分重要的功能模块, 那就是进程管理.
3. 进程管理
3.1 什么是进程/任务 (Process/Task)
每个应用程序运行于现代操作系统之上时, 操作系统会提供一种抽象, 好像系统上只有这个程序在运行, 所有的硬件资源都被这个程序在使用. 这种假象是通过抽象了一个进程的概念来完成的, 进程可以说是计算机科学中最重要和最成功的概念之一.
进程是操作系统对一个正在运行的程序的一种抽象, 换言之, 可以把进程看做程序的一次运行过程. 同时, 在操作系统内部, 进程又是操作系统进行资源分配的基本单位.
简单来说, 一个运行起来的程序, 就是进程.
.exe
的是一种可执行文件(程序), 当双击这个文件, 程序就会跑起来, 我们就会打开QQ, 从而就在操作系统中形成了一个进程.
我们也可以打开任务管理器Ctrl + Alt + Delete
来查看系统中都在进行哪些进程.
可以看到, 系统中有这么多进程都在同时运行. 就是由于进程多了, 所以操作系统才需要去管理进程, 否则这么多进程, 会导致操作系统卡死的.
3.2 进程管理怎么做的
所谓的管理, 其实就是分两步:
- 描述一个进程: 使用结构体或者对象, 把一个进程有哪些信息都表示出来.
- 组织这些进程: 使用一定的数据结构, 把这些结构体或对象都放到一起.
在Java中就是对象的概念, 在C++中就是结构体的概念
3.3 进程控制块抽象PCB (Process Control Block)
计算机内部要管理任何现实事物, 需要将其抽象成一组有关联的, 互为一体的数据. 在 Java 语言中, 我们可以通过类/对象来描述这一特征. 而在操作系统中是用PCB来描述的.
注: 操作系统往往使用 双向链表 这样的数据结构来组织 PCB.
// 以下代码是 Java 代码的伪码形式,重在说明,无法直接运行
class PCB {
// 进程的唯一标识 —— pid
// 内存指针
// 文件描述符表
// 进度调度属性
}
PCB的核心属性:
- pid
每个进程需要有一个唯一的标识符, 有点类似于数据库中的主键. - 内存指针
描述当前这个进程使用的是哪一部分内存.
进程要跑起来, 就需要消耗一定的硬件资源, 比如内存. 而内存指针就是用来描述进程运行的时候, 使用了哪些内存上的资源. - 文件描述符表
硬盘上存储的数据, 往往是以文件为单位来进行整理的.
进程每打开一个文件, 就会产生一个 “文件描述符” (用来标识这个被打开文件), 一个进程可能打开很多文件, 对应了一组文件描述符. 把这些文件描述符放到一个顺序表这样的结构里, 就构成了文件描述符表. - 进程调度属性
在讲进程调度属性前, 我们先引入一个 CPU 的概念, 计算机中的程序能运行, 全得依靠 CPU, 每个程序相当于一组 “二进制指令” 的集合, 在CPU 中有一个概念, 核心数.
这个截图是我计算机的核心数, 8核16线程表示, CPU 中有8个核心, 但是每个核心一个顶两, 8个人就可以干16个人的活, 即8个物理核心, 16个逻辑核心.
而我们计算机中通常会有很多进程需要同时处理.
那么计算机是如何用少数人来完成多数人的工作的呢? 下面我再介绍一下并行和并发的概念.
并行: 同一时刻, 两个核心, 同时执行两个进程, 此时这两进程就是并行执行的.
并发: 一个核心, 先执行进程1, 执行一会儿后, 再去执行进程2, 再执行一会儿后, 又去执行进程3… 此时只要这里的切换速度足够的快, 进程123看起来就像是 “同时” 执行的一样.
此时, 虽然我的计算机只有16个核心, 也可以同时执行这137个进程了, 就是通过 并行 和 并发 的方式来完成的.
接下来这一组属性, 都是用来描述和 CPU 资源相关的属性, 这些属性来辅助进行进程调度.
3.3.1 进程调度属性
- 进程的状态
简单认为, 进程主要有两种状态:- 就绪态: 表示该进程已经准备好, 随时可以上 CPU 执行.
- 阻塞态: 表示该进程还未准备好, 暂时无法上 CPU 执行.
- 进程的优先级
进程之间的调度不是完全公平的, 有的进程要优先调度. - 进程的上下文
上下文, 就是描述当前进程执行到哪里, 当进程离开 CPU 时, 就要把当前运行的中间结果 “存档记录”, 等到下次进程回来 CPU 上的时候, 再恢复之前的 “存档”, 也就是进行 “读档”, 从上次的结果继续往后执行.
如果进程结束了, 就不必进行存档, 如果是暂时离开, 就得存.
而读档存档在进程中, 是靠 CPU 内部的一系列寄存器来实现的. 寄存器有很多种, 其中最典型的作用, 就是保存当前进程执行的中间结果, 包括进程运行到哪一条指令.- 存档: 进程离开 CPU, 就需要把这些寄存器的值, 保存到 PCB 的上下文字段中.
- 读档: 进程回来 CPU, 再把 PCB 中的值给恢复到寄存器中.
- 进程的记账信息
用来统计每个进程, 在 CPU 上执行了多久, 可以作为进程调度的参考依据.
4. 内存分配 ---- 内存管理 (Memory Manage)
我们再了解一下内存管理的概念: 操作系统对内存资源的分配, 采用的是空间模式 ---- 不同进程使用内存的不同区域, 互相之间不会干扰.
简单来说, 就是操作系统给进程分配的内存, 是以 “虚拟地址空间” 的方式来进行分配的, 每个进程访问的内存地址, 都不是真实的物理内存地址.
站在左边这两进程的角度看, 他们代码中操作的内存地址, 都是 0x00 - 0xff 这一段, 但是这里访问的内存就会被操作系统自动映射到真实的物理内存上, 但是进程本身感知不到实际的物理地址是啥.
5. 进程间通信 (Inter Process Communication)
如上所述, 进程是操作系统进行资源分配的最小单位, 这意味着各个进程互相之间是无法感受到对方存在的, 这就是操作系统抽象出进程这一概念的初衷, 这样便带来了进程之间互相具备 “隔离性(Isolation)”.
但现代的应用, 要完成一个复杂的业务需求, 往往无法通过一个进程独立完成, 总是需要进程和进程进行配合地达到应用的目的, 如此, 进程之间就需要有进行“信息交换“的需求. 而进程间通信的需求就应运而生.
目前, 主流操作系统提供的进程通信机制有如下:
- 管道
- 共享内存
- 文件
- 网络
- 信号量
- 信号
其中, 网络是一种相对特殊的 IPC 机制, 它除了支持同主机两个进程间通信, 还支持同一网络内部非同一主机上的进程间进行通信.
简单来说, 所谓进程间通信, 就是在隔离性的前提下, 找一个公共的区域, 让两个进程借助这个区域来完成数据交换.
总结
✨ 感谢你们的耐心阅读, 博主本人也是一名学生, 也还有需要很多学习的东西. 写这篇文章是以本人所学内容为基础, 日后也会不断更新自己的学习记录, 我们一起努力进步, 变得优秀, 小小菜鸟, 也能有大大梦想, 关注我, 一起学习。
感谢你们的阅读, 你们的鼓励是我创作的最大动力!!!!!