浅谈进程调度

       要想了解进程调度,我们首先得知道什么是进程,那么什么是进程呢?其实进程就是正在运行的程序,如此说来,是不是就认为一个程序只能有一个进程,其实不然,同一个程序运行多次可能会出现多个进程。如我们多次点击浏览器,就会有多个浏览器的窗口,这也就使得同一个程序有着多个进程。通常我们说的程序,只是一个可执行文件,而把可执行文件里的数据和指令加载到内存中,并且让cpu去执行这里的指令,完成一系列相关的任务的运行起来的程序,也是动态的程序,此时这个东西就是进程。

        进程能完成一系列的任务,就说明它要消耗一定的硬件资源,如cpu资源,内存资源,网络带宽,硬盘等等,那么可执行文件是否需要呢?其实它只占了硬盘空间,因为此时它并没有运行起来,因此与其他的文件并没区别,单纯的存储在硬盘上罢了。因为进程它会消耗一定硬件资源,因此也可以说进程是系统分配资源的基本单位。一个运行了的电脑,它一定有着许多进程,进程多了,那么就必须得进行管理。那么怎样进行管理呢?计算机中针对进程的管理采取的是先描述,再组织的思路。先描述指的是使用一个专门的结构体,记录每个进程的各个属性。再组织指的是使用一系列的数据结构,把多个进程进行一个有效的组织,随时方便进行遍历等操作。但是如果进程的数量非常少,如只要俩仨个,那么则不会考虑先描述,再组织。并且这个专门的结构体的结构体也有着一个专门的名字:PCB(进程控制块),而再组织通常是用双向链表的方式进行组织(针对Linux来说)。当使用双向链表进行组织时,查看进程的列表,本质上是遍历这个链表。创建一个进程,就是创建一个PCB结构体,并且插入到链表上。销毁一个进程,就是把这个PCB结构体从链表上删除并释放。Linux里的PCB结构体为task_struct结构体。描述进程的部分都可以称为PCB。

        说了这么多PCB,那么PCB里到底有些什么呢?

1)pid:进程的标识。同一个系统中,同一时刻的进程,它们的pid都是不同的。

2)内存指针:表示该进程对应的内存资源(主要是可执行文件加载过来的指令(代码的逻辑,交给CPU来执行)和数据)是怎样的。

3)文件描述符表:和硬件资源有关。硬盘是硬件,应用程序一般是没法直接接触到硬件这一层的,实际上是操作系统抽象成文件这样的概念,程序操作的是文件,文件实际上是存储在硬盘上的。每个进程都会有一个文件描述符来记录当前这个进程正在使用那些文件,操作系统每打开一个文件,就会产生一个文件描述符(就像文件的身份标识一样,不过只是再进程内部生效),同时会使用文件描述符表(类似数组)把文件描述符组织起来。

        既然进程通常都较多,那么操作系统如何对进程进行调度呢?不可能一个一个调用吧。当然,操作系统调用进程主要有两种方法,一种是并发,一种是并行。

1)并行:两个或者多个进程在不同的CPU逻辑核心上同时运行。

2)并发:多个进程轮流在同一个CPU逻辑核心上运行。(由于cpu在切换进程时速度极快,因此在宏观上,应用程序感觉不出来,但系统内核感觉的出来,由于宏观上感觉不到,通常也会用并发代指并发和并行)。

操作系统在调用这些进程时,可能按照的时并发,也有可能按照的是并行的方法来调用。

        同样,PCB中也有着关于进程调度相关的属性(这些属性也就描述了进程对应的CPU资源对应的使用情况)。

1)状态:就绪状态:进程已经做好了随时在CPU上执行的准备。

                阻塞状态:进程没有做好被CPU执行的准备。

实际上进程在系统中不只有这两种状态,但它们是最关键的状态。

2)优先级:系统给进程进行调度的时候,也不是完全公平的,也会根据优先级的不同,来决定时间分配的权衡,就可以把系统资源调配给更重要的进程。

3)上下文:因为进程是轮着上的,一次运行不完,就需要保证下次上CPU运行的时候,能够从上次运行到的位置,继续往后运行,而上下文就充当这个记录当前位置的角色,也就是存档和读档。对于操作系统来说,所记录的的上下文是该进程在执行过程中,CPU的寄存器所对应的数据,这些寄存器有的是存一些中间结果,有的是存一些特定含义的数据(如当前函数的调用关系),这些数据就需要在进程离开cpu之前都保存好,保存到对应进程的pcb的上下文字段中。下次再次调用该进程时,就可将pcb的上下文里的数据回复到对应的寄存器中,如此,进程就和上次执行的状态一模一样。

4)记账信息:相当于一个统计信息。会统计每个进程在cpu上都执行了多久,执行了多少个指令等。

        每个进程都需要有一定的内存资源,早期的操作系统就是直接把物理内存(电脑上的内存条)分配给进程,这就带来一个严重问题,一旦内存访问越界,就可能影响到别的进程,后来操作系统就引入了“虚拟地址空间”的概念,虚拟地址并非是在物理内存上真实存在的地址,而只是该进程内存在,不同的进程中,可以存在相同的虚拟地址,但是实际上对应到的时不同的物理地址,虚拟地址和物理地址可以被操作系统进行灵活的转换。但对于应用程序来说,只能见到虚拟地址而见不到真实的地址。这样设定之后,每个进程的有效虚拟地址都是固定范围,进程使用该虚拟地址的内存,都需要操作系统进行转换成物理地址的过程,这个转换过程中,就可一针对虚拟地址是否有效做出一个校验,提高了系统的稳定性,通过虚拟地址空间,把进程隔离开了,但是有些时候,还需要让进程之间,产生点配合和联系,也就是进程间通信,就要在进程隔离性的基础上,开个口子,让进程间能够有限制的进行相互影响。

你可能感兴趣的:(多线程)