对于内存管理告一段落,今天正式开始进入内存管理的章节,首先从基础学习,主要是包括进程线程基础概念篇,主要包括以下内容
早期的计算机一次只能执行一个任务,采用批处理的方法,由监督系统完成作业的切换,使得作业一个接一个的被处理,如下图所示
对于该批处理系统内存中仅有一道程序运行,即每次监督器只能从磁带上调入一道程序进入内存中运行,当该程序完成或发生异常时,才换入其他后续程序进入内存运行,这就是早期的批处理系统。但是随着计算机的发展趋势,这种已经不能满足越来越复杂的场景需求
对于上面的程序A和程序B,如果在单道程序设计中,需要80个时间周期才能执行完,而采用多道程序设计,A程序等待的时候,B程序可以调度执行,相同的操作只需要45个时间周期就能完成,其效率如下所示
单道程序 | 多道程序 | |
---|---|---|
CPU利用率 | 40/80=50% | 40/45=89% |
DEV1利用率 | 15/80=18.75% | 15/45=33% |
DEV2利用率 | 25/80=31.25% | 25/45=56% |
所以,对于这种批处理系统, 每次上机时, 我和其他程序都排好队, 一个接一个的进入内存运行。但是这种效率低下,为了创建和谐社会,促进效率和公平, 充分发挥每一个人的能力,所以就引入了多道程序设计的概念。
主要是为了提高CPU利用率,人们设计了在一台计算机实现能将多个程序同时加载、并发执行,从而引入进程的概念。
- 每个加载到内存中的程序都称为进程,操作系统管理者多个进程并发执行。
- 进程会认为自己独立占用CPU资源
进程是指一个具有一定独立功能的程序在一个数据集合上的一次动态执行过程。其如下图所示
由上图可以知道,进程包含了正在运行的一个程序的所有的状态的信息,其主要包括以下
进程是操作系统处于执行状态程序的抽象
同一程序的多次执行过程对应为不同的进程
进程执行是需要资源
进程是操作系统中调度的一个实体,需要对进程所拥有的资源进行抽象,这个抽象的形式就是进程控制块(PCB),主要是用来管理控制进程运行所用的信息集合。
对于进程控制块需要描述以下信息
因此,进程描述符是用于描述进程运行状态以及控制进程运行所需要的全部信息,是操作系统用来感知进程存在的一个非常重要的额数据结构。任何一个操作系统的实现都需要一个数据结构来描述进程描述符,所以linux内核采用一个名为task_struct的结构体,该内容后面详细学习。
对于进程的上下文切换,如下图所示
一个进程的生命周期可以划分为一组状态,这些状态刻画了整个进程。进程状态即体现一个进程的生命状态。进程的整个生命周期如下
在linux系统中,许多进程在诞生之初都与其父进程共同用一个存储空间。但是子进程又可以建立自己的存储空间,并与父进程“分道扬镳”,成为与父进程一样真正意义上的进程。
linux系统运行的第一个进程是在初始化阶段“捏造出来的”。而此后的线程或进程都是由一个已存在的进程像细胞分裂一样通过系统调用复制出来的,称为“fork()”或者“clone()”引起进程创建的情况
进程的创建解决了从无到有的过程,而当进程创建后,就处于就绪状态,进程具备运行条件,等待系统分配处理器以便运行。
而进程的执行是内核选择一个就绪的进程,让它占用处理器并执行,主要是从就绪状态切换到运行态的过程,但是这里面涉及到如何选择哪个就绪队列,采用何种算法,这个后面会单独学习
指进程不具备运行条件,正在等待某个事件的完成,此时进程进入等待(阻塞)的状态,其有如下情况
只有进程自身才知道何时需要等待某种事情的发生,该过程只能发生在运行态到等待态的。
进程抢占可能发生在两种情况下:
无论进程当前运行在内核态还是用户态,都可以发生抢占,被抢占的进程仍然运行在TASK_RUNNING状态。
唤醒进程的情况
进程只能被别的进程或操作系统唤醒
进程结束的情况
我们来看看sleep系统调用对应的进程状态的变化情况,如下图
我们来实现看看进程切换的完成状态图,如下图示
每次执行中的进程必须完全载入内存中,因此所以队列中的所有进程必须驻留在内存中。内存中保存多个进程,当一个进程正在等待,处理器可以转移到另外一个进程,但是CPU比I/O要快很多,以至于内存中所有进程都在等待I/O的情况就显得很常见。那么我们该如何处理这种问题呢?
不同于进程阻塞。挂起时没有占用该内存空间,而是映像在磁盘上,主要是减小进程占用内存。类似虚存中,有的程序段被放到了硬盘上。
等待挂起状态:该状态是由等待状态切换,进程在外出中并等待某事件的出现
就绪挂起状态:进程在外存中,但只要进入内存,即可运行
本章主要是学习了操作系统为何要引入进程这个概念,为了提高CPU利用率。多批道处理系统一次性载入多个作业到内存中让程序并发执行,但这会造成一系列的问题,引入进程这些问题得以解决,同时也学习了进程的相关的概念。但是随着人们需求越来越多,对于并发的要求越来越高,单纯的进程已经不能满足于日常的需求,此时就导致线程的概念的产生。