进程的状态
三种状态
- 运行态:该时刻实际占用 CPU 的进程。
- 就绪态:可运行但还没有被分配时间片。一般在就绪队列中。
- 阻塞态:除非某种外部事件发生,否则进程无法运行。一般在阻塞队列中。
四种转换关系
- 运行 -> 阻塞:一般操作系统发现进程因缺少某种条件无法运行下去的时候,发生这种转换。在一些系统中,进程可以执行诸如 pause 的系统调用进入阻塞状态。在 Unix 等系统中,当进程从管道或者设备文件读取数据时,如果没有有效输入,也会自动阻塞。
- 运行 -> 就绪:一般由于正常进程调度发生这种转换。可能是当前 CPU 上的进程时间片用完了,也可能 CPU 因某种外部事件发生了中断。可以通过 yield 系统调用主动让出 CPU。
- 就绪 -> 运行:这种转换也一般是正常进程调度导致的。根据进程调度策略决定哪个就绪进程被调度。
- 阻塞 -> 就绪:当进程等待的外部事件发生时,产生这种转换。一般是通过中断通知阻塞进程转换为就绪状态。
进程的层次结构
Windows
没有层次结构的概念,所有进程的地位都相同。唯一类似进程层次的暗示是创建进程时,父进程会得到一个特别的令牌(句柄),该句柄可以用来控制子进程。但是,父进程有权把句柄送给其它进程。在 Unix 中,这种剥夺继承权的行为是不被允许的。
Unix
进程组
进程和它所有子进程以及后裔共同组成一个进程组。当用户从键盘发出一个信号时,该信号被送到当前与键盘相关的进程组中的所有成员(通常是当前窗口创建的所有活动进程)。每个进程可以分别捕获该信号,忽略该信号或采取某个动作。
Unix 启动时如何初始化
init 进程启动 -> 读入中断数量说明文件 -> init 为每个终端创建一个进程,这个进程等待用户登录 -> 登录成功后启动 shell 进程,等待用户输入命令 -> shell 接收命令启动更多进程。因此,在 Unix 中,所有进程都是属于以 init 为根的一颗进程树。