以下内容均为本人学习笔记,如有不当,感谢指出
什么是进程?
对于这个问题,教科书上一般都会这样解释
总结下来就是:进程是程序运行的实例,是操作系统中资源分配的基本单位
这样讲感觉还是有点抽象
谈论进程,我们可以认为它是一个活体,只是给出概念怕是很难形容,我们可以从进程是如何运作的,运作时都依靠哪些资源来表述进程。
每个进程都拥有自己独立的地址空间,在LINUX操作系统中,每个进程在内核中都有与之对应的一个进程控制块结构(PCB)来描述进程。很明显进程的所有资源都和它PCB中的内容息息相关,那就可以看看PCB中都有哪些内容来对就进程进行展开描述
进程控制块结构
a)进程ID为了表示进程的唯一性,PCB中有一个的进程标识符信息来标识进程的唯一性,用来区别其他进程
b) 资源并且如上所描述的,进程是程序运行的实例,那么必定每一个进程都拥有自己的资源,包含进程都执行哪些代码,至于代码和数据在何处存放,PCB中内存指针信息指向了进程对应的虚拟地址空间中哪部分是代码,哪部分是数据。
当进程拥有的代码和数据,其实就可以运行起来了。
c)但是由于CPU资源有限,不能同时满足多个进程,为了进程的正常调度,操作系统就得做出相应的补救措施,以及进程本身为了配合而做出相应的措施。
为了有序调度,每个进程之间是有优先顺序也就是进程优先级,这样的话对于同一时间到达的进程,操作系统就可以根据优先级配合相应调度机制合理进调度。
并且每个进程有与之对应的进程状态信息来表示当前进程处于哪个状态,供操作系统调度时参考。
d)同样,当进程调度出去时,为了能正常的调度回来,操作系统为每个进程维护了当前进程执行时寄存器中的数据,也称为上下文信息保存在进程PCB中。并且对于进程什么时候从CPU上调度下来,以及在CPU上执行的时间总和等信息,进程也应该将其信息记录下来,即PCB中的记账信息
e)每个进程在运行过程中会打开一些文件,对应的应当将这些文件信息保存下来,以便于后面文件的管理和关闭,当然这些文件并不存放在进程的PCB中
进程PCB中有一个files_struct
的结构体指针,指向一个files_strucr 结构体中包含了一个file *
类型的数组,(还包含exec时需要关闭的文件,文件屏蔽字等信息),file *
数组的下标我们称为文件描述符,每个数组元素指向一个file
结构体,这个结构体里包含了文件信息(文件系统信息,文件路径等信息),里面的 int_fileno
字段封装了文件描述符。
f)每个进程的结构体中对应有对信号的标识,未决信号集和信号屏蔽字(阻塞屏蔽集),来保存当前进程中有哪些信号以及阻塞了哪些信号。
有了上面的概念,就可以知道进程是如何运作起来的。知道了进程都会占据哪些资源,也就理解了进程是作为操作系统中的最小的资源分配单位。
补充
例如,进程的状态有如下几种
R 运行状态(并不意味之一定处于运行状态,也包含就绪状态)
S 睡眠状态 (可中断睡眠)
D 磁盘休眠状态(不可中断睡眠状态)
T 停止状态 (可通过信号 SIGSTOP
和SIGCONT
控制)
X 死亡状态(我们并不能看到状态,因为进程已经退出)
Z 僵尸状态 (子进程退出,父进程还在,但是父进程没有读取子进程退出状态,子进程就进入僵尸状态)
子进程就会一直处于僵尸状态来等待父进程读取退出状态码,此时,因为父进程没有回收子进程的资源,而导致内存泄漏。
避免僵尸进程的方法有2种:
1.父进程在子进程结束之后进行等待子进程,回收其资源,wait
方法阻塞式等待和waitpid非阻塞式等待。
2.忽略子进程退出状态,进程结束之后会向父进程发送一个 SIGCHLD信号,若父进程对该信号处理方式为 SIGIGN(忽略),则内核会在子进程结束后自动回收子进程资源,避免内存泄漏。