17-睡着延迟
10.6.3 睡着延迟
睡着延迟无疑是比忙等待更好的方式,睡着延迟在等待的时间到来之间进程处于睡眠状态,CPU资源被其他进程使用。schedule_timeout()可以使当前任务睡眠指定的jiffies之后重新被调度执行,msleep()和msleep_interruptible()在本质上都是依靠包含了scheduletimeout()的schedule timeout_uninterruptible()和schedule_timeout_interruptible()实现的,如代码清单10.15所示。
代码清单10.15 schedule_timeout()的使用
1 void msleep(unsigned int msecs)
2 {
3 unsigned long timeout = msecs_to_jiffies(msecs) + 1;
4
5 while (timeout)
6 timeout = schedule_timeout_uninterruptible(timeout);
7 }
8
9 unsigned long msleep_interruptible(unsigned int msecs)
10 {
11 unsigned long timeout = msecs_to_jiffies(msecs) + 1;
12
13 while (timeout && !signal_pending(current))
14 timeout = schedule_timeout_interruptible(timeout);
15 return jiffies_to_msecs(timeout);
16 }
实际上,schedule_timeout()的实现原理是向系统添加一个定时器,在定时器处理函数中唤醒参数对应的进程。
代码清单10.15第6行和第14行分别调用schedule_timeout_uninterruptible()和scheduletimeout interruptible(),这两个函数的区别在于前者在调用scheduletimeout()之前置进程状态为TASK INTERRUPTIBLE,后者置进程状态为TASK_UNINTERRUPTIBLE,如代码清单10.16所示。
代码清单10.16 schedule_timeout_interruptible()和schedule_timeout_interruptible()
1 signed long _ _sched schedule_timeout_interruptible(signed long timeout)
2 {
3 _ _set_current_state(TASK_INTERRUPTIBLE);
4 return schedule_timeout(timeout);
5 }
6
7 signed long _ _sched schedule_timeout_uninterruptible(signed long timeout)
8 {
9 _ _set_current_state(TASK_UNINTERRUPTIBLE);
10 return schedule_timeout(timeout);
11 }
另外,下面两个函数可以将当前进程添加到等待队列中,从而在等待队列上睡眠。当超时发生时,进程将被唤醒(后者可以在超时前被打断):
sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout);
interruptible_sleep_on_timeout(wait_queue_head_t*q, unsigned long timeout);