进程(process)
什么是进程?
一般的, 一个程序(也就是一个可执行文件), 当运行之前, 这个程序是"静态"的, 当我们双击点开这个程序的时候, 操作系统就会把这个可执行文件的关键信息加载到内存中, 这个时候就会开始运行里面的代码, 从而就形成进程(简单来说进程是运行可执行文件时形成的).
进程管理
在我们操作系统上, 肯定是会有多个进程同时在跑的, 为了使这些进程在跑起来的时候不会相互影响, 这时候就引入了进程管理. 进程管理是操作系统内核的功能. 进程的管理分为两步: 1. 描述: 使用类 / 结构体将进程里面的特征都表示出来, 这个结构体就称为是PCB(进程控制块); 2. 组织: 使用数据结构, 将很多个这样的类 / 结构体整理到一起.
PCB(进程控制块)
一个进程里面是可以有多个PCB的, 而在操作系统内核中, 就会将这些PCB串成一个双向链表.那么, 在PCB里面都会有那些信息呢?
- 进程的身份标识 pid 内存指针: 操作系统需要把一些必要的数据加载到内存中, 而这部分的数据就是由内存指针来表示的, 内存指针会会描述在一个进程中哪些部分是运行的指令, 哪些部分是数据. 文件描述符表: 表示当前进程打开的文件, 当每打开一个文件的时候, 就会在进程的文件描述符表中分配一个 表项 给这个文件. 其中, 这个文件描述符表本质上是一个顺序表, 顺序表中的每个元素都存着一个打开的文件, 而这些元素对应的下标就称为"文件描述符".
进程的调度
在了解了进程是啥之后, 也是需要知道进程是如何调度的. 一般的, 会通过一下的四种方式来确定进程的调度.
- 进程的优先级: 顾名思义, 操作系统会根据不同的进程进行判断, 确定这些进程谁先谁后. 进程的状态: 操作系统在安排进程先后顺序的时候, 会考虑不同进程的状态, 在某些特定的情况下执行某个进程. 进程的记账信息: 操作系统在安排进程的时候, 往往会通过一些先前的记录来执行某个进程. 进程的上下文: 一个进程在执行某一个操作的时候, 有可能会出现执行一半就被调度走的情况, 而在一段时间后(可能会出现执行完其他进程的情况)再返回来执行这个进程, 这时候就需要使用到进程的上下文来调取上一次执行一半时存下来的数据. 上下文表示的其实就是进程在被切出CPU的时候, 会把当前寄存器的状态保存到PCB中, 当后面这个进程重新回到CPU的时候, 就会把PCB中的上下文给读取出来执行.
进程的虚拟空间
同时, 在进程调度的时候, 多个进程之间可能会出现相互干扰的问题, 对此, 操作系统就引入了"虚拟地址空间", 其作用是让每个进程都只能访问到自己的地址空间, 相互之间就不会再出现干扰的情况, 即使指针指向是错误的, 操作系统内部也是可以很快地排查到问题所在, 不会去影响到其他进程.
因为有了这些虚拟地址空间, 从而使得进程具备了隔离性(相信在看文章的你早已非常熟悉隔离性了, 之前文章中MySQL中的事物以及多线程中的锁操作都涉及到隔离性了). 正因为有了这个隔离性, 一个进程的运行一般并不会影响到另外一个进程, 尤其是在一个进程崩溃的时候也是不会影响到其他进程的.
进程间通信
我们在前面让不同的进程之间产生了隔离性, 这确实会让系统变得更加稳定了, 但是正像前面所说的, 凡事都是有两面的, 这时候可能会出现其他的问题 — 如果多个进程之间要进行配合工作的时候, 就可能会因为隔离性而受阻. 这时候, 操作系统就又引入了"进程间通信", 进程之间进行通信主要做法都是在多个进程之间创建一个公共资源, 然后借助这个公共资源来进行通信. 这样就可以很好地让多个进程之间进行配合工作.
线程(thread)
什么是线程?
线程可以说是进程中的一部分, 因为一个线程是只包含一个PCB的, 而前面也说了一个进程当中是可以对应有多个PCB的, 所以说, 一个进程中是可以包含有多个线程的.
多个线程共用一个进程中的资源
形如上面多个进程之间并发执行的过程, 就叫做并发编程. 但是在这种单纯地使用进程的情况下, 会出现大量地创建和销毁进程, 但是这样的操作是非常的低效的, 就以创建进程为例: 需要进行下面的这三步操作: 1. 创建PCB; 2. 分配系统资源(内存资源), 这一步操作消耗的时间是最大的; 3. 将PCB加入到内核的双向链表当中去. 这时候为了提高效率, 就出现了线程(也叫作"轻量级进程"), 多个线程是可以同时存在于同一个进程里面的, 而一个线程就对应着一个PCB, 这时候这些线程就可以这个进程中的资源(也就是共用同一份系统资源), 在创建线程的时候也就省去了创建进程中消耗时间最多的第二步, 只剩下: 1. 创建PCB; 2. 将PCB加入到内核的双向链表当中去.
总结进程和线程的联系与区别(重点)
- 进程是包含线程的, 线程在进程的内部 每个进程都有自己独立的虚拟地址空间(也就是说进程之间的资源是相互独立的), 也有自己独立的文件描述附表; 同一个进程的多个线程之间, 则是会共用这个进程的资源以及文件描述符表. 进程是操作系统中资源分配的基本单位, 线程是操作系统中调度执行的基本单位. 多个进程同时执行的时候, 如果其中一个进程崩溃了, 一般是不会影响到其他进程的; 同一个进程内部的多个线程之间, 如果一个线程挂了, 是很有可能使整个进程都崩溃的, 这样的话, 就会让同个进程中的其他线程都挂掉.
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/291205.html