1. 什么是进程
进程就是运行中的程序。比如在计算机上打开一个记事本文件,这个记事本文件的运行在操作系统里就是一个进程,再打开另一个记事本文件又是另一个进程。
每个进程都有自己的资源,如内存地址空间(存放代码,数据和栈),CPU资源(程序计数器,各种寄存器等),文件,总之,与程序执行有关的信息都在进程中。
2. 为什么需要进程
- 假设现在计算机中有一个程序正在执行,此时来了一个优先级更高的程序,但它只能等待前一个程序执行完才能开始。
- 程序执行的不同阶段需要的资源是不一样的,有的时候CPU在执行算术逻辑运算,有的时候需要等待IO,在做IO操作时,CPU是空闲的,如果此时能让另一个需要CPU操作的程序来执行,就能避免CPU浪费。
为了解决上述两个场景的问题,使多程序能够并发执行,引入了进程这一概念。CPU在不同进程之间快速地切换,营造出一种每个应用都独占CPU的假象。
3. 进程的生命周期
3.1 创建进程
创建进程的四种情境
- 系统初始化
操作系统启动的时候会创建大量进程,有些是在前台做用户交互的,有些是在后台完成特定任务的,比如等待接收邮件的进程,等待接收web请求的服务器进程等等,在后台运行的进程也被称作daemons守护进程。 - 父进程创建子进程
一个服务器端进程收到用户请求之后,可以创建一个新的进程来处理,而自己继续等待。这种互不影响又可以拆分的任务就可以交给新的进程来执行。 - 用户创建
用户每次启动一个新的程序都在创建新的进程。 - batch job创建新进程
一般在大型机上执行一个batch job时,操作系统会自动根据资源使用情况决定是否增加一个新进程来启动下一个任务。
如何创建进程
- Linux 创建进程
Linux只提供了一个创建进程的system call: fork. 操作系统会给调用fork的进程创建一个一模一样的子进程,相同的内存镜像,相同的环境变量,相同的打开文件等等,即child process完全copy parent process的PCB和stack, 并修改自己的pid. 进程创建结束之后child process可以调用execve 或类似的system call改变自己的内存镜像,运行新的程序。 - windows 创建进程
windows创建进程的方法是CreateProcess.
进程的层级结构
- process group
在UNIX系统中,一个进程和它的所有子进程和后代进程构成了一个process group. 当用户通过键盘发出一个signal以后,signal会传递给进程组中的所有进程。 - 进程树
UNIX系统启动以后 init/systemd进程启动,为每个terminal创建一个process等待用户登录,用户登录以后,login process执行shell接收用户命令,这些命令又会启动新的进程,所以整个系统都属于一个以init/systemd为根的进程树。
3.2 终止进程
进程终止的四种情境
- 正常退出
进程执行结束。 - 发生错误主动退出
进程发现错误,如用户输入了错误的参数,进程主动退出。 - 发生错误被动退出
通常由程序错误导致,如执行了非法指令,访问了不存在的内存地址,被操作系统结束。 - 被其他进程杀死
如何终止进程
- exit
程序主动调用exit - kill
从外部结束一个进程
进程资源清理
进程结束后先变成僵尸进程,经父进程或1号进程尸检后释放资源(PCB,页表等)。
3.3 进程状态
- Running
进程正在CPU中运行 - Ready
进程可以运行,但由于此时CPU被分配给了其他进程,只能等待CPU分配给自己 - Blocked
进程由于一些外部的依赖没准备好不能运行,如等待IO
进程状态转换
3.4 如何实现进程
进程的数据结构
操作系统为了在不同进程之间切换,首先要知道都有哪些process,其次要记录每一个process的执行状态和内存,文件等资源使用情况。记录所有process的数据结构叫做 process table, 记录单个process信息的数据结构叫 process control block(PCB). process table就是由PCB构成的。不同的操作系统对PCB有不同的实现,但基本上都会包括下面这些信息:
Process Management | memory management | file management |
---|---|---|
Registers | Pointer to text segment info | Root directory |
Program Counter | Pointer to data segment info | Working directory |
Program Status Word | Pointer to stack segment info | File descriptors |
Stack Pointer | User ID | |
Process State | Group ID | |
Priority | ||
Scheduling Parameters | ||
Process ID | ||
Parent Process | ||
Process Group | ||
Signals | ||
Time when process started | ||
CPU Time Used | ||
Children's CPU Time | ||
Time of Next Alarm |
进程切换
中断(时钟中断或IO中断或其他中断)发生时,中断硬件将当前正在执行的进程的PC, PSW, 寄存器等信息保存到进程的stack内存(入栈),然后跳转到对应的中断处理程序入口,OS开始执行中断处理程序。等调度器重新选择此进程时,CPU将栈顶信息重新加载进CPU便能从上次中断的位置继续执行。这就是保存现场和恢复现场。