每日阅读5之linux内核设计与实现——linux内核调度之睡眠与唤醒

来源:互联网 发布:杭州seo异同 编辑:程序博客网 时间:2024/05/17 09:03

进程休眠(被阻塞)的原因有很多种,但都是在等待某一种事件

(1)文件I/O磁盘读取,键盘输入等硬件事件

(2)获取一个已经被占用的内核信号量等。。。


操作

休眠:进程把自己标记成休眠状态,从可运行红黑树中移出,加入等待队列,调用schedule()选择和执行一个其他进程

唤醒:进程被设为可执行状态,从等待队列中移到可执行红黑树


休眠的进程可能出于二种状态,但位于同一等待队列

(1)task_interruptible

(2)task_uninterruptible,忽略信号(所有信号?)


等待队列

休眠通过等待队列进行处理,等待队列是等待某种事件发生的进程的集合。。

内核使用wake_queue_head_t表示等待队列,可以通过DECLARE_WAITQUEUE()静态创建或init_waitqueue_head动态创建。


为避免产生竞争条件,休眠与唤醒的内核实现较为繁杂

比较典型的是先将进程加入等待队列,再去检查等待条件是否满足,这样避免了在条件已经满足的条件下,仍然休眠的问题。

在许多地方,实际的实现要更加的复杂,对条件的检测更为严格,可能要用到锁。。


当某个事件满足后,相应的模块就要调用wake_up来唤醒对应于该事件的等待队列上的所有进程,并将其放入可运行红黑树,若有进程的优先级比当前运行进程的优先级要高,则在抢占式内核当中,需要设置其need_resched标志。

例如如果磁盘数据到达,VFS模块就要负责唤醒工作


另一个概念就是伪唤醒,即如前所述,等待队列中的状态为TASK_INTERRUPTIBLE的进程会对信号进行处理,此时并不是真正的等待事件到达。。。



OVER!!!




原创粉丝点击