【图解八股-操作系统篇①-进程与线程】

作者简介和专栏内容见专栏介绍:https://www.nowcoder.com/creation/manager/columnDetail/0eL5bM

麻烦看到贴子的伙伴点点赞大家点赞订阅支持下,提前祝各位offer多多,有问题评论区见~~

图解版

进程和线程相关

从源头举例子介绍为什么有进程,顺便提进程状态和调度(挖坑)->为什么出现线程,之后分析各自的作用与优缺点

为什么有进程

现在我们考虑有一个会读取硬盘文件数据的程序被执行了,那么当运行到读取文件的指令时,就会去从硬盘读取数据,但是硬盘的读写速度是非常慢的,那么在这个时候,如果 CPU 傻傻的等硬盘返回数据的话,那 CPU 的利用率是非常低的。所以,当进程要从硬盘读取数据时,CPU 不需要阻塞等待数据的返回,而是去执行另外的进程。当硬盘数据返回时,CPU 会收到个中断,于是 CPU 再继续运行这个进程。这种多个程序、交替执行的思想,就有 CPU 管理多个进程的初步想法。

为什么要有线程?当时设计操作系统的人设计线程的目的是什么?线程解决什么问题?

线程是进程中的一个执行单元,可以让进程同时执行多个任务1。当时设计操作系统的人设计线程的目的是为了提高系统的并发性和效率2。线程解决了传统进程只能在一个时间干一件事,或者在等待输入时无法执行其他工作的问题。

进程、线程和协程的区别和联系

线程与进程的比较

线程与进程的比较如下:

  • 进程是资源(包括内存、打开的文件等)分配的单位,线程是 CPU 调度的单位;
  • 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;
  • 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系;
  • 线程能减少并发执行的时间和空间开销;

线程相比进程能减少开销,体现在:

  • 线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们;
  • 线程的终止时间比进程快,因为线程释放的资源相比进程少很多;
  • 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的;
  • 由于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了;

所以,不管是时间效率,还是空间效率线程比进程都要高

在Linux中进程和线程

在 Linux 中,进程和线程的实现方式是相同的,也就是说,Linux 中的线程本质上就是一种“轻量级进程”,它们共享同一个地址空间和资源,因此可以互相访问和修改对方的数据。这种实现方式被称为“线程共享进程虚拟地址空间”。

在 Linux 中,进程和线程都是由 `task_struct` 结构体表示的,两者的区别在于:

1. 进程是一个独立的执行单元,它有独立的地址空间、文件描述符、信号处理等资源。进程可以通过 `fork()` 系统调用创建子进程,每个进程都有自己的 PID(进程标识符)。

2. 线程是一个共享进程资源的执行单元,它与其他线程共享同一个地址空间和文件描述符表。线程可以通过 `pthread_create()` 系统调用创建,每个线程都有自己的 TID(线程标识符)。

在 Linux 中,进程和线程之间的切换是通过操作系统内核的调度器实现的。调度器会根据预设的调度算法,选择合适的进程或线程执行,并将 CPU 时间分配给它。由于 Linux 中的线程和进程实现方式相同,因此可以将线程看作是一种特殊的进程,也就是说,在 Linux 中,进程和线程的区别并不是非常明显,甚至可以说是模糊的。

进程地址空间

多进程和多线程的区别是什么?换句话说,什么时候该用多线程,什么时候该用多进程?

频繁修改:需要频繁创建和销毁的优先使用多线程

计算量:需要大量计算的优先使用多线程因为需要消耗大量CPU资源且切换频繁,所以多线程好一点

相关性:任务间相关性比较强的用多线程,相关性比较弱的用多进程。因为线程之间的数据共享和同步比较简单。

多分布:可能要扩展到多机分布的用多进程,多核分布的用多线程

但是实际中更常见的是进程加线程的结合方式,并不是非此即彼的。

线程私有和共享资源

同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。

线程进程切换时的上下文切换具体指什么,包含哪些东西

进程线程发生切换的场景

一个进程可以创建多少线程,和什么有关?

理论上,一个进程可用虚拟空间是2G,默认情况下,线程的栈的大小是1MB,所以理论上最多只能创建2048个线程。如果要创建多于2048的话,必须修改编译器的设置。

因此,一个进程可以创建的线程数由可用虚拟空间和线程的栈的大小共同决定,只要虚拟空间足够,那么新线程的建立就会成功。如果需要创建超过2K以上的线程,减小你线程栈的大小就可以实现了,虽然在一般情况下,你不需要那么多的线程。过多的线程将会导致大量的时间浪费在线程切换上,给程序运行效率带来负面影响。、

  • 32 位系统,用户态的虚拟空间只有 3G,如果创建线程时分配的栈空间是 10M,那么一个进程最多只能创建 300 个左右的线程。
  • 64 位系统,用户态的虚拟空间大到有 128T,理论上不会受虚拟内存大小的限制,而会受系统的参数或性能限制。

线程的优缺点

进程调度算法你了解多少?

1、 先来先服务 first-come first-serverd(FCFS)

非抢占式的调度算法,按照请求的顺序进行调度。

有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。

2、 短作业优先 shortest job first(SJF)

非抢占式的调度算法,按估计运行时间最短的顺序进行调度。

长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。

  1. 高响应比优先调度算法

前面的「先来先服务调度算法」和「最短作业优先调度算法」都没有很好的权衡短作业和长作业。

那么,高响应比优先 (Highest Response Ratio Next, HRRN)调度算法主要是权衡了短作业和长作业。

每次进行进程调度时,先计算「响应比优先级」,然后把「响应比优先级」最高的进程投入运行,「响应比优先级」的计算公式:

3、最短剩余时间优先 shortest remaining time next(SRTN)

最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。

如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。

4、时间片轮转

将所有就绪进程按 FCFS 的原则排成一个队列,每次调度时,把 CPU 时间分配给队首进程,该进程可以执行一个时间片。

当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送往就绪队列的末尾,同时继续把 CPU 时间分配给队首的进程。

时间片轮转算法的效率和时间片的大小有很大关系:

  • 因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频 繁,在进程切换上就会花过多时间。
  • 而如果时间片过长,那么实时性就不能得到保证。

5、优先级调度

前面的「时间片轮转算法」做了个假设,即让所有的进程同等重要,也不偏袒谁,大家的运行时间都一样。

但是,对于多用户计算机系统就有不同的看法了,它们希望调度是有优先级的,即希望调度程序能从就绪队列中选择最高优先级的进程进行运行,这称为最高优先级(Highest Priority First,HPF)调度算法

为每个进程分配一个优先级,按优先级进行调度。

为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级(动态优先级)。

6、多级反馈队列

一个进程需要执行 100 个时间片,如果采用时间片轮转调度算法,那么需要交换 100 次。 多级队列是为这种需要连续执行多个时间片的进程考虑,它设置了多个队列,每个队列时间片大小都不 同,例如 1,2,4,8,..。进程在第一个队列没执行完,就会被移到下一个队列。 这种方式下,之前的进程只需要交换 7 次。每个队列优先权也不同,最上面的优先权

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

计算机实习秋招全阶段指南 文章被收录于专栏

作者简介:2个月时间逆袭嵌入式开发,拿下理想汽车-ssp、小米汽车-sp、oppo-sp、迈瑞医疗、三星电子等八家制造业大厂offer~ 专栏内容:涵盖算法、八股、项目、简历等前期准备的详细笔记和模板、面试前中后的各种注意事项以及后期谈薪、选offer等技巧。保姆级全阶段教程帮你获得信息差,早日收到理想offer~

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务