长延时-1

在内核中,以jiffies为单位的进行的延迟通常被认为是长延时。

一种可能但非最佳的实现长延时的方法是忙等待,它本身不利用CPU进行有用的工作,同时还不让其他应用使用CPU。

来个示例:

unsigned long timeout = jiffies + HZ;

while(time_before(jiffies, timeout)) {
    cpu_relax();
}

对cpu_relax的调用将以架构相关的方式执行,其中不执行大量的处理器代码。在许多系统上,该函数根本不会做任何事情;而在对称多线程(“超线程”)系统上,它可能将处理器让给其他线程。但不论是哪种情况,只要可能,我们都应该尽量避免使用这种方式。

 

实现长延时的更好方法是睡眠等待而不是忙等待,在这种方式中,本进程会在等待时将处理器出让给其他进程。

schedule_timeout便能实现此功能:

/**
 * schedule_timeout - sleep until timeout
 * @timeout: timeout value in jiffies
 *
 * Make the current task sleep until @timeout jiffies have
 * elapsed. The routine will return immediately unless
 * the current task state has been set (see set_current_state()).
 *
 * You can set the task state as follows -
 *
 * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
 * pass before the routine returns. The routine will return 0
 *
 * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
 * delivered to the current task. In this case the remaining time
 * in jiffies will be returned, or 0 if the timer expired in time
 *
 * The current task state is guaranteed to be TASK_RUNNING when this
 * routine returns.
 *
 * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
 * the CPU away without a bound on the timeout. In this case the return
 * value will be %MAX_SCHEDULE_TIMEOUT.
 *
 * In all cases the return value is guaranteed to be non-negative.
 */
signed long __sched schedule_timeout(signed long timeout)

这种延时仅仅确保超时较低时的精度。由于只有在时钟节拍引发的内核调度才会更新jiffies,所以无论是在内核空间还是在用户空间,都很难使超时的精度比HZ更大了。另外,即使你的进程以及超时并可被调度,但是调度器仍然可能基于优先级策略选择运行队列的其他进程。

这个函数还有以下一些变种:

/*
 * We can use __set_current_state() here because schedule_timeout() calls
 * schedule() unconditionally.
 */
signed long __sched schedule_timeout_interruptible(signed long timeout)
{
	__set_current_state(TASK_INTERRUPTIBLE);
	return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_interruptible);

signed long __sched schedule_timeout_killable(signed long timeout)
{
	__set_current_state(TASK_KILLABLE);
	return schedule_timeout(timeout);
}
EXPORT_SYMBOL(schedule_timeout_killable);

signed long __sched schedule_timeout_uninterruptible(signed long timeout)
{
	__set_current_state(TASK_UNINTERRUPTIBLE);
	return schedule_timeout(timeout);
}

用于睡眠等待的另外两个函数是wait_event_timeout和msleep,它们的实现都基于schedule_timeout。

wait_event_timeout的使用场合是:在一个特定的条件满足或者超时发生后,希望代码继续运行。

msleep表示:睡眠指定的时间(以毫秒为单位)。

 

这种长延时技术仅仅适用于进程上下文。睡眠等待不能用于中断上下文。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值