进程,是对正在运行的程序的一个抽象。
进程
CPU由一个进程快速切换至另一个进程,使得每个进程运行几十或几百毫秒,从而产生一种并行的错觉。
进程模型
一个进程就是一个正在执行程序的实例,包括程序计数器、寄存器和变量当前值。从概念上说,每个进程拥有自己的虚拟CPU。实际上真正的CPU在进程之间来回切换。这种快速的切换称作多道程序设计。
由于CPU在各个进城之间来回快速切换,因此每个进程执行其运算的速度是不确定的。而且,当同一个进程再次运行时,其运算速度通常也是不可再现的。所以,在对进程编程时,决不能对时序做任何想当然的假设。
如果一个程序运行两遍,则算作两个进程。例如开启两个Word文件。像“两个进程恰好运行同一个程序”这样的事实,其实是无关紧要的。
进程的创建
四种会触发进程创建的事件:
1、系统初始化
2、正在运行的程序执行了创建程序的系统调用。
3、用户请求创建一个新进程
4、一个批处理作业的初始化
守护进程(daemon):停留在后台处理诸如电子邮件、web网页之类活动的进程。
基于命令行的Unix系统中运行程序X,新的进程会从该进程接管开其他的窗口。
Windows系统中,多数情形是这样的,在一个进程开始时,他并没有窗口,但是他可以创建一个或多个窗口。
新进程的创建,都是由于一个已经存在的进程,执行了一个用于创建进程的系统调用而创建的。这个进程所做的工作就是,执行一个用来创建新进程的系统调用,这个系统调用通知操作系统创建一个新进程,并且直接或间接的制定该进程中运行的程序、
进程创建之后,父进程和子进程有各自不同的地址空间。如果其中某个进程在其地址空间中修改了一个字,这个修改对其他进程而言是不可见的。进程之间,可写的内存是不可以共享的。
进程的终止
触发进程终止的条件:
1、正常退出(自愿)——例如Unix中调用exit来实现完成工作之后的进程的自动退出。
2、出错退出(自愿)——当进程发现了严重错误的时候,会自动退出,比如当用户键入编译某文件的命令,而该文件并不存在时。
3、严重错误(非自愿)——当进程内部引起错误的时候,会执行该退出。通常是有程序错误引起的,比如执行了一条非法指令、引用不存在的内存,或者除数是零等。
4、被其他进程杀死(非自愿)——kill命令
当一个进程终止时,不论是否是自愿的,该进程所创建的所有进程也一律被杀死。
进程的层次结构
进程只有一个父进程。
Unix系统中,进程和他创建的子进程以及后裔共同组成进程组。当用户从键盘发出信号时,该信号被送给当前与键盘相关的进程组中的所有成员。每个进程可以分别不活该型号、忽略该信号或采取默认的动作,即被该信号杀死。
Windows系统中没有进程层次的概念,所有的进程地位相同。唯一类似于进程层次的按时是在创建进程的时候,父进程得到一个特别的令牌(称为句柄),该句柄可以用来控制子进程。但是他有权把这个令牌传送给其他进程,这样就不存在层次了。在Unix系统中,进程就不能剥夺其子进程的“继承权”。
进程的状态
1、运行态——该时刻进程实际占用CPU
2、就绪态——可运行,但是引起其他进程在占用CPU,所以运行暂停
3、阻塞态——当进程正在等待某个资源的时候,如果获取到资源,则进程继续执行,否则,进程不能运行
进程的三种状态有四种可能的转换关系。
操作系统最底层是调度程序,在他上面有许多进程。所有关于中断处理、启动进程和停止进程的具体细节都被隐藏在调度程序中。
进程的实现
为了实现进程模型,操作系统维护着一张表格(一个结构数组(这个表格是怎么实现的?)),即进程表(process table)。每个进程占用一个进程表项。该表象包含进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况和电镀锌线等,从而保证该进程随后能再次启动。
多道程序设计模型
采用多道程序设计模型可以提高CPU的利用率。如何计算CPU的利用率?这里用到了概率论的知识。
假设一个进程等待I/O操作的时间与其停留在内存中的时间的比为p。当程序中同时又n个进程时。则所有n个进程都在等待I/O的概率为p的n次幂。因此,CPU的利用率为:
CPU利用率=1-p的n次幂
n称为多道程序设计的道数。