进程(process)
目录
- 进程(process)
- 1. 进程--即一个**跑起来**的运用程序
- 2. 进程 可视为是操作系统进行资源分配的基本单位
- 3. 在操作系统中,通常使用称为 PCB 这样的结构体来描述进程的.
- 4. PCB
- 5. 文件描述符(重点)
- 6. 进程调度(关键重点)
- 1. PCB 提供了几个属性,支持 进程调度
- 1. 状态
- 2. 优先级
- 3. 上下文
- 4. 记账信息
1. 进程–即一个跑起来的运用程序
在任务管理器中,显示的则是所有进程.这些除了上述自己运行的程序外,还有一些系统自带/安装的某些程序.
在这个表中,表示给某程序分配的各类资源大小.
要想让一个程序运行,就必须给这个进程 分配系统资源.
2. 进程 可视为是操作系统进行资源分配的基本单位
一旦 作为基本单位的进程 多了, 就要考虑管理
管理需要 先描述,后组织.
1.描述: 通过一些结构体/类,把一个进程的核心信息抽象提取出来,并进行表示
2.组织: 通过一定的数据结构,把多个这样的 结构体/类 的对象 串联起来,方便进一步的各种增删改查.
3. 在操作系统中,通常使用称为 PCB 这样的结构体来描述进程的.
PCB(process control block): 进程控制块,内核里的结构体.
不同操作系统代码名不同,在 Linux 系统上 类如 PCB 的命名为: task_struct.
结构体中就需要包含一些进程的核心信息,操作系统中通常会使用 链表 这样的结构,把多个PCB串联起来.(这里的 “链表” 则是多个链表综合在一起构成的).
举个栗子:
- 我们在 任务管理器中查看进程列表,就是在遍历 链表 的每个节点,并且获取显示对应的信息.
- 创建新的进程(双击某个程序运行), 新的进程创建出一个对应的新的 PCB,并且添加到上述链表中.
- 销毁某个进程(某个程序退出), 要把链表上对应的 PCB 节点给删掉.
以上的操作,则就是一些 数据结构代码.
再举个栗子:
比如,双击一个快捷方式, 打开steam进程,本质上是 文件资源管理器(应用程序)感应到鼠标的双击操作, 然后调用操作系统提供的 API(Application Programming Interface----程序之间的接口), 在内核中创建 进程(创建PCB, 插入链表).
4. PCB
PCB 像是一个小本子, 记录这一些信息
- pid(process id)
进程的 id / 进程的标识符.
这些进程均是运行 steam.exe 产生的
得出
同一个机器,同一时刻,进程的id一定是不同的
- 内存指针
指向 进程的 指令 和 数据.
进程运行时,需要消耗一定的硬件资源,内存就是一个关键的资源.一个程序在运行的时候, 就会被 从硬盘加载到内存中.
而指针 并非是一个指针,而是一组指针.一组指针标明要运行的 指令(进程下一步的操作) 都在内存的 哪个地址上, 和进程依赖的 数据, 又在哪些地址上.
举个栗子
public class Test {public static void main(String[] args) {System.out.println("hello");}
}
以上则为一个保存在硬盘上的可执行文件.
Test.exe文件中 包含了 System.out.println(); 对应的一系列二进制 指令 (里面调用系统 api 等等).也包含了 “hello” 这样的 数据.
双击 exe, 此时操作系统会产生一个进程 —> 创建 PCB ,再把 PCB 加入到内核的链表中(把 exe 中的 指令 和 数据 加载到内存中).
图示:
5. 文件描述符(重点)
一个进程运行时,会操作一些文件,通过一个 “顺序表” 这样的数据结构, 记录当前的进程都打开了哪些文件.
在此不再展开…
6. 进程调度(关键重点)
任务管理器中, 系统中包含了很多进程, ,每个进程都需要执行, 执行就需要去占用 CPU 资源, 去 CPU 上执行. 但进程的数量远远多于 CPU 的数量.
这样如何处理呢?
我们采用 进程调度, 分时复用
并行执行:
一个核心,同一时刻,只能运行一个进程, 有 16 个核心, 同一时刻, 同时运行 16 个进程.(同时进行,)
并发执行:
一个核心, 不同时刻, 可以执行不同的进程
这一刻,执行进程1, 下一刻, 执行进程2, , 再下一刻,执行进程3.
由于时间片较短, CPU 切换进程的速度极快, 人感知不到,(本质不是同时). 被称为并发执行
操作系统会按照 并行 + 并发 相互搭配,运行所有进程
并行 微观时间上, 也是同时执行.
并发 宏观时间上, 是同时进行,微观时间上, 是串行执行.
因此,往往把 “并行 + 并发” 统称为 “并发”. 把编写解决并发问题的程序, 称为 “并发编程”.
1. PCB 提供了几个属性,支持 进程调度
1. 状态
就绪状态
“随叫随到”
阻塞状态
处于阻塞状态的进程, 无法在 CPU 上执行,往往这个基础在等待 IO 的时候就会进入阻塞状态.
scanner.next();
遇到以上代码则处于阻塞状态
2. 优先级
分配时间时,不一定是完全公平的, 可能存在倾斜
谁需要的多看多给谁, 谁需要的少就少给谁
3. 上下文
即 小本子, 进程在 CPU 上执行时, 会产生很多的 “中间结果”( CPU 的各种寄存器的值).
存档: 在进程切换出 CPU 之前. 需要把中间结果保存到 PCB 的 上下文 里(寄存器 --> 内存).
读档: 下次进程回到 CPU , 就需要把之前的存档恢复,(内存 --> 寄存器).
4. 记账信息
因为分配时间资源可能不同, 则采用记账信息, 即 表格, 用来统计数据,
操作系统也要避免某个进程一直吃不到信息, 则会进行类似的统计, 给吃的少的进程, 适当的多分配些资源.