Blocking Process
当一个进程process被设置为非活动状态时,它就被认为是阻塞blocking或等待waiting的,直到有发生特定事件。
进程阻塞 Blocking Process
阻塞的进程通常正在等待诸如信号量被释放或消息到达其消息队列之类的事件。 在多任务系统中会期望这样的进程用系统调用通知调度器它要等待,以便它们可以从活动调度队列中删除,直到有需要的事件发生。 在等待时继续运行的进程 (即,在紧密循环中连续轮询事件) 被称为 busy-waiting,这是不可取的,因为它浪费了可用于其他进程的时钟周期。
休眠 Sleeping
等待的一种特殊情况是休眠,这是指在给定的时间段 (例如20毫秒) 内将进程设置为非活动状态。 主要是出于效率的考虑,休眠通常有一套区别于普通等待的单独处理策略; 由于时钟中断是很频繁的,并且跟踪每次时钟中断是不可行的,因此通常的方法是使用相关的计数器系统来标记给定进程何时被唤醒。
用于跟踪休眠进程的常用数据结构是delta队列,这是一个有序的休眠进程列表,其中每个进程都有一个计数器,该计数器相对于之前列表中的最后一个进程偏移; 例如,如果进程A沉睡3个周期,进程B沉睡5个周期,进程C沉睡5个周期,进程D沉睡8个周期,那么列表将是
{A, 3} -> {B, 2} -> {C, 0} -> {D, 3}
在每个时钟周期时,最顶层进程的计数器都会递减,如下所述:
{A, 2} -> {B, 2} -> {C, 0} -> {D, 3}
如果此时添加了过程E,等待6个时钟周期,则它将在D之前插入,并且E和D都将适当地更新:
{A, 2} -> {B, 2} -> {C, 0} -> {E, 2} -> {D, 1}
如果最上面的进程达到零,那么它 -- 以及紧随其后的任何同样为零的进程 -- 都将被放回活动调度队列中。 因此,在2个周期之后,A被设置为活动的; 2个周期之后,B和C都被设置为活动的; 依此类推。这种方法的优点是最大程度地减少了给定时钟周期中所需的更改数量。
可中断和不中断
通常清晰的区分可中断等待/休眠和不中断等待/休眠是一个好主意。 根据你的系统,你可能希望大多数等待状态可中断,尽管你几乎肯定会需要一些不间断状态。 你可能需要考虑在不可中断等待之上构建可中断等待,而不是使用特殊标志。