【进程与线程】最好懂的讲解

  • Post author:
  • Post category:其他



作者简介


目录


1.CPU的管理


2.进程


2.1.概述


2.2.数据结构


2.3.进程状态


2.4.进程与内存


2.5.PCB队列


3.线程


3.1.概述


3.2.实现


1.CPU的管理

进程和线程是操作系统里面的概念,这个概念其实是对CPU的管理策略。整个操作系统都可以看作计算机硬件的管理软件,而进程和线程则是对于CPU的管理。

CPU作为计算机的核心,其职责概括起来就是:


取指执行。

CPU是一个只知道处理指令的部件,而具体处理什么指令则有程序计数器来决定。程序计数器就像CPU的饲养员,会不断地给CPU传去要执行的指令在内存中的地址,CPU则执行取指指令,去对应地址中拿要执行的指令,然后执行。整个流程如下图所示:

整个cpu的取指过程中存在几个问题:

  • 利用率不高

  • 缺少控制


利用率不高:

假设CPU在执行某一个程序的指令,那么他就会连续去执行这个程序的指令代码,当整个程序有慢速的操作,比如IO操作之类的,由于IO的速度要远远低于CPU的速度,那么CPU会在一段时间内处于等待IO的状态。等待的这段时间以CPU的效率来说要是用去执行其它任务,能执行很多内容。


缺少控制:

程序之间存在轻重缓急,比如当前CPU正在运行一个打印文件的程序指令,由于要和IO设备打交道,这个程序是比较耗时间的。此时进来了一条发射核弹的程序指令,明显优先级高的

程序等到优先级低的程序执行完毕,而且前一条指令合适执行完毕,完全无从得知。


解决以上问题的思路:


让CPU在程序之间切来切去,让程序交替执行。

不让程序一口气执行完,而是将CPU的时间分成时间片,这一秒属于程序A,下一秒属于程序B,下一秒又属于程序A…让程序交替的去执行,这样的话即使遇到了诸如IO这种耗时操作也能利用其期间的空闲时间。比如一个IO操作本来要三秒,也就是说CPU从执行这个IO操作开始要苦等三秒钟才能能到返回结果,但是时间分片、程序交叉执行后,假设时间片分成了一秒一个,这一秒遇见了IO,下一秒分给了其他程序,下一秒再回来,这样中间的时间就被利用起来了。

2.进程

2.1.概述

前面我们说到为了充分利用CPU,需要将CPU时间分片、程序交叉执行。但是这样做之后随之就有一个问题是要解决的:

如何描述运行中的程序?

要让程序切来切去就一定要对这些运行的程序进行描述,要描述某个程序执行到了何处之类的消息。这样来回调度的时候才能接着上次继续运行。当然对线程的描述肯定不止一个上次运行到哪里这一个内容还有很多细节的内容,比如可以给每个运行中的程序一个优先级,优先级大的多分点时间片给它,也需要给每个运行中的程序一个编号好进行区分。注入此类的一堆的对运行中的程序的描述叫做——进程。

进程的定义:

用于描述和管理程序的“运行过程”。是指程序在某个数据集合上的一次运行活动。是

分配资源的一个基本单位

进程的特点:

  • 并发性,由于CPU在程序间切来切去的执行,使得多个进程会有种被并发执行的感觉。

  • 独立性,进程是分配资源和运行调度的基本单位。

进程雨程序的区别:


程序是静态的,是一组指令放在存储中,长期存在。


进程式动态的,是程序的一次执行过程,短期存在。


一个程序可能有多个进程。

2.2.数据结构

进程由三部分组成:

  • PCB

  • 代码

  • 数据

数据和代码没什么好讲的,程序要执行肯定要这些东西,重点要注意一下PCB。

进程控制块(Process Control Block,PCB):用来记录比如当前执行到了何处、优先级、名称等重要消息。PCB在创建进程时被创建,进程撤销时同时被撤销。PCB是操作系统管理进程的单位。

2.3.进程状态

理论上进程有三种状态:

运行态(Running):进程占有CPU,在CPU上运行。 就绪态(Ready):具备运行条件,暂未运行,等待CPU资源。 阻塞状态(Block):已经开始执行的进程,在执行过程中等待某个资源。也叫等待状态(wait)。 以上只是理论上的三种必须的基本状态,各类型操作系统的具体实现会有差异。

2.4.进程与内存

进程与内存 每个程序的数据和代码装入内存空间,每个进程都会有独立的一个对应的数据结构(内存管理中的页表)来记录该进程的数据和代码存放在哪些位置。 每个程序装入内存,生成对应的一个进程,进程生成时,会同时生成属于该进程的PCB,PCB中会记录页表项,即当前程序执行到了何处。 CPU会根据PCB队列来调度执行各个进程。

2.5.PCB队列

等待被调度执行的进程:

对应的还有阻塞队列等,都是类似上图的结构。 CPU会根据调度算法从就绪队列中选择进程来执行,当执行的进程无法继续推进时,将该进程暂时放入阻塞队列,重新从就绪队列中选一个进程来执行,之前进程重新准备好后,某个时间点上CPU再切回来继续推进该进程。

3.线程

3.1.概述

线程我们可以理解为对进程进行了多路复用,线程的出现带来两个优势:

  • 程序之间的切换更加轻量级

  • 并发度更高

1.程序之间的切换更加轻量级:

进程之间的切换会造成CPU上下文的切换,性能开销很大,如果对CPU上下文不是很了解的同学可以移步:


详解CPU的态__BugMan的博客-CSDN博客

2.并发度更高:

我们来举个例子:

假设在CPU的某个时间片里要执行如下指令:

第一行代码调用IO设备后,即使已经完成使用,后续不再需要此资源,但是在第N行代码执行结束前,IO设备仍然被该进程所占有,其它要用到该资源的进程只能等待。当然在单CPU架构中不会存在这个问题,但是一旦是多CPU的架构中就会出现这种情况。

3.2.实现

线程的实现有两种:

  • 用户级线程

  • 内核级线程


用户级线程:

用户在程序层面通过手动编码的方式来实现逻辑上的线程,通过编码来手动实现线程的切换逻辑,即在用户空间的调度以线程为单位,在CPU上的调度以进程为单位。


内核级线程:

用户空间的调度以进程为单位,CPU的调度以线程为单位。

总结起来说,线程可以理解为对进程的多路复用,当操作系统支持线程时,CPU的上下文切换仍然是以进程为单位进行的。线程的控制块称为TCB,作用和结构和进程几乎是一样的,属于同一个进程的线程的TCP存储于该进程的内存空间中。



版权声明:本文为Joker_ZJN原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。