当我们提到操作系统这个话题,绕不过去的就是进程和线程这个话题,他们有什么联系,又有什么区别?本文我们将详细对这两个概念进行辨析.
目录
一.进程
1.进程理解
2.进程管理
3.进程调度
并行和并发
4.为什么有线程
二.线程
三.进程与线程的区别
四.多进程和多线程的区别
首先,什么是进程呢?
我们的手机上都装了各种各样的软件,当一个软件开始运行,这样,就形成了一个进程.
那么与之相对应的,操作系统也是一个软件,所以当一个软件或者程序运行起来的时候,一个进程就形成了.
这个时候,我们再来看进程的定义:进程是一个具有一定独立功能的程序在一个数据集合上依次动态执行的过程。进程是一个正在执行的程序的实例,包括程序计数器、寄存器和程序变量的当前值。
怎么样,是不是能理解了呢?
当然,一个操作系统上不可能只运行一个软件或程序,一般来说,会有很多进程同时在电脑上运行,我们可以在任务管理器里进行查看.
我们能直观看到有很多进程,正因有如此多的进程,我们才需要进程管理.
那么,怎么进行进程的管理呢?
我们描述一个进程,是使用结构体/类,把一个进程有哪些信息表示出来
而组织这些进程:使用一定的数据结构,把这些结构体/对象放到一起
进程里的结构体有很多属性,我们现在只挑重要的来说.
PCB(process control block)
1.pid(编号) : 每一个进程需要有一个唯一的身份标识
2.内存指针: 当前这个进程使用的内存是哪一部分;进程运行的时候,使用了哪些内存上的资源.
3.文件描述符表 : 进程运行的时候,使用了哪些硬盘上的资源
由此可见,当一个进程运行的时候,和资源是分不开的,这里的资源就包括但不限于内存,硬盘,CPU等.
进程运行是需要从操作系统这里申请资源的,因此,我们说,进程是操作系统进行资源分配的基本单位
所以我们管理进程,其实就是管理这些资源.而其中最重要的资源,就是CPU.有了CPU,我们就能进行进程调度,所以接下来,我们就来详细介绍这里的内容.
我们的程序能运行,全依仗于CPU !!! 每个程序,相当于一组“二进制指令”的集合~~
而CPU 有一个概念,核心数~~
比如8核16线程,就像是,CPU 里有8 的干活的人,但是每个核心,一个顶俩,8 个人就可以同时干16 个人的活.同时,我们也衍生出了并发和并行的概念.
并行
同一时刻,两个核心,同时执行两个进程此时这俩进程就是并行执行的并发
一个核心,先执行进程1, 执行一会之后,再去执行进程2,再执行一会之后,再去执行进程1,此时只要这里的切换速度足够快,看起来,进程1 2 就是“同时”执行.
此时,虽然咱们只有 16 个核心, 但是通过并发+并行的方式,我们就可以同时执行多个任务了.
(一般"并发+并行" 完全是操作系统自身控制的.我们是感知不到的,所以很多时候就把 "并发+并行"统称为并发).
当并发程度更高了,就可以称为高并发了.比如一个核心(主体) 并发执行 了1w 个任务,就可以称为"高并发".
好的,现在我们回到进程.接下来这一组属性都是描述和 CPU 资源相关的属性,这些属性都是辅助进行进程调度.
1.进程状态
我们简单认为,进程状态主要是这两个:
当多个程序运行的时候,就要"排队等待",轮到谁就可以上CPU执行.
2.进程的优先级
而当多个进程运行时,进程之间的调度不一定是“公平”的.
有的运行时间段,消耗资源少,有的执行速度快,所以有了优先调度.
3.进程的上下文
在进程里面,所谓的上下文具体指就是进程运行过程中,CPU 内部的一系列寄存器的值.
不同的寄存器有不同的作用,而在进程管理中,最典型的作用就是保存当前进程执行的中间结果,包括进程运行到哪一条指令.
根据前面讲到的并发,当进程离开 CPU时,电脑就需要把这些寄存器的值保存到 PCB 的上下文字段中,等到进程下次回来的时候,再把 PCB 中的值给恢复到存器中.这就是进程的上下文.
4.进程的记账信息
记账信息就是统计了每个进程在 CPU 上执行了多久,这个可以作为调度的参考依据.
通过统计这些资源和属性,我们就能对资源实行很好的调度.
操作系统往往使用 双向链表 这样的结构来组织 PCB
- 创建一个进程,就是创建一个 链表的节点
- 销毁一个进程就是把链表的节点给删除了
- 遍历进程列表就是在遍历链表
因此进程是比较“重量的”.这里的重量就指进程的"速度慢"以及消耗资源多.
资源分配往往是一个耗时操作.比如系统要给进程分配一块内存
- 系统就需要遍历自己的空闲内存的表(数据结构)找到一个大小差不多的空间, 进行分配
- 很多个进程都在问系统申请资源, 系统进行资源分配的时候得一个一个来
因此,多进程编程可以解决并发编程的问题,但并不是一个高效的选择.
线程,是更轻量的进程,(轻量级进程)
线程被设计成进程的一个执行路径,同一个进程中的线程共享进程的资源,因此系统对线程的调度所需的成本远远小于进程。
我们来看这样一个示意图:
从图中我们可以认识到:
进程包括线程
一个进程中可以包含多个线程
每个线程都是一个独立可以调度执行的“执行流
多个线程之间,也是并发执行的.
同一个进程的多个线程共用同一份系统资源.
意味着,对于线程而言,系统资源是已经分配好了的,创建线程就省下了分配资源开销.
也就是说,只有在进程启动,创建第一个线程的时候,需要花成本去申请系统资源目进程(第一个线程)创建完毕,此时,后续再创建的线程,就不必再由请资源了.创建/销毁 的效率就提高了不少.
本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
资源开销:每个进程都有独立的地址空间,进程之间的切换会有较大的开销;线程可以看做轻量级的进程,同一个进程内的线程共享进程的地址空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
影响关系:一个进程崩溃后,在保护模式下其他进程不会被影响,但是一个线程崩溃可能导致整个进程被操作系统杀掉,所以多进程要比多线程健壮。
举个例子,多线程下载一个歌曲或者视频的时候,可以同时运行多个线程,但是我们观察程序运行的结果发现,每一次结果都不一致。
这是因为多线程存在一个特性:随机性。而造成的结果就是,CPU需要在瞬间不断切换去处理各个线程,也就可以理解成多个线程在抢CPU资源。
因此我们得到结论:多线程并不能提高运行速度,但可以提高运行效率,让CPU的使用率更高。但是如果多线程有安全问题或出现频繁的上下文切换时,运算速度可能反而更低。