进程概念
进程是程序在某个数据集合上的一次执行活动
ps:一个程序运行两遍算作两个进程
进程与程序的区别
相对于程序来说,进程是活的,具有完整的生命周期,有动态的产生和消亡的过程;而程序就是一段代码(code),是死的。
进程的组成
进程由程序(code),处理数据(data)和程序控制块(PCB, Process Control Block)组成。
ps:为了实现进程模型,操作系统维护着一张进程表(process table),每个进程占用一个表项,这些进程表项(PTE, Process Table Entry)也被称为程序控制块(PCB)。在表项中记录了进程的重要信息,包括程序计数器,堆栈指针,内存分配情况,打开文件的状态以及其他进程在由运行态转换到阻塞态或是就绪态必须保存的信息,保证进程随后能再次启动,就像从未被中断过一样。
多道程序设计
一个CPU在某一时刻只能运行一个进程。
CPU在多个进程之间快速切换,宏观来说,一段时间后所有的程序都运行了,但严格意义上说,每一时刻只有一个程序正在执行。这种快速切换称作多道程序设计。
具体一些的实现:举个书上的例子
a)中,四个进程每个进程都有自己的逻辑程序计数器,实际上只有一个物理程序计数器。每个程序运行时,自己的逻辑程序计数器被装入实际的程序计数器中;程序执行结束(或者暂停执行)时再把物理程序计数器保存在相应程序的逻辑程序计数器中。
ps:多处理器系统是指系统有多个CPU共享同一个物理内存,从而实现真正意义上的并行。
进程的层次结构
UNIX
在UNIX操作系统中,每个进程都以某种形式保持关联,每个进程(除了init)都有父进程。
UNIX系统中的进程可以用进程树(Process Tree)表示出来。
子进程执行结束会进入到僵尸态(zombie state),父进程在子进程执行结束,或者用户要求结束子进程时对子进程的管理数据,控制信息等进行清理。
在子进程结束之前父进程要结束,为避免子进程变成孤儿进程,有两种处理方式:第一种就是先把自己的所有子进程杀死,然后再由自己的父进程结束自己;第二种时将子进程托付给进程init,成为init的子进程。
Windows
在WIndows操作系统中,每个进程都是独立的个体。
进程的创建
4个主要事件会导致进程的创建:
1.系统初始化
比如UNIX系统在启动时会创建一个特殊进程init,这个进程作为该系统下所有进程的祖先进程,并且一直存在直到系统关闭
2.进程执行创建进程的系统调用
例如UNIX系统中的fork()
3.用户请求创建一个新进程
例如在Windows系统中双击图标或者输入命令
4.一个批处理作业的初始化
UNIX系统中的进程创建
UNIX系统中,通过一个系统调用来创建新进程:fork()
这个系统调用会创建一个与调用进程完全相同的进程,两个进程表项具有相同的内存映像,环境字符串和打开文件(可以理解为具有相同的执行代码和处理数据);然后子进程执行execve()或类似的系统调用,来修改子进程的内存映像(更换自身的代码段,引入新的处理数据),然后运行这个新的程序。
在上面的示例中,如果pid(process id)也就是fork()的返回值为大于0的数,就说明该进程为父进程,父进程中的waitpid()也是一个系统调用函数,是父进程在等待子进程执行结束,子进程执行结束时会唤醒父进程来清理僵尸态;如果pid为0,说明该进程为子进程,子进程中的execlp()与execve()是同一族的系统调用函数;如果pid小于0,说明子进程创建失败。
进程的状态
运行(running):一个CPU同一时刻只能运行一个进程,所以只有一个进程处于运行态
就绪(ready):可运行,等待CPU分配运行时间
阻塞(blocked):逻辑上不能运行,比如缺少可以使用的输入
过程2:程序分得的时间片使用完,让出CPU,由调度程序收回供给其他的进程使用
过程3:调度程序从已经就绪的进程中选一个分配运行时间
过程1:程序缺少继续执行的资源或者信号(比如可用的输入),因此主动的进入阻塞状态
过程4:程序需要的资源得到满足时,被其他的程序(占用资源的进程归还资源时,或者发出响应信号的进程)唤醒,进入到就绪态等待分配时间片
进程的终止
1.由程序主动终止。程序工作已经完成,或程序出错退出(比如没能打开某个文件),程序自愿2终止。UNIX系统中,程序终止变成僵尸态,由父进程来清理PCB。
2.出现严重错误。程序非自愿的退出。比如,执行非法指令,引用不存在的内存等。UNIX系统中,进程可以告诉操作系统自行处理这类错误,因此会引发中断,而不是直接终止。
3.被其他进程杀死。UNIX系统中的系统调用函数kill()可以实现。