Linux内核中的延时函数详解
内核中涉及的延时主要有两种实现方式:忙等待或者睡眠等待。前者阻塞程序,在延时时间到达前一直占用CPU,而后者是将进程挂起(置进程于睡眠状态并释放CPU资源)。所以,前者一般用在延时时间在毫秒以内的精确延时,后者用于延时时间在毫秒以上的长延时。为了充分利用 CPU 资源,使系统有更好的吞吐性能,在对延迟时间的要求并不是很精确的情况下,睡眠等待通常是值得推荐的。
1、忙等待短延时
内核中提供了如下3个函数用于纳秒、微秒和毫秒级的延时:
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs); //一般不建议直接使用mdelay()函数,这将无谓地耗费 CPU 资源
上述延迟的实现原理本质上是忙等待,它根据 CPU 频率进行一定次数的循环。其本质同如下代码:
void delay(unsigned int time)
{ while (time--);
}
2、忙等待长延时函数
内核中进行延迟的一个很直观的方法是比较当前的 jiffies 和目标 jiffies(设置为当前 jiffies 加上时间间隔的 jiffies),直到未来的 jiffies 达到目标 jiffies。
- 利用jiffies和time_befor实现延时100个jiffies和2秒的代码:
/*延迟 100 个 jiffies*/ unsigned long delay = jiffies + 100; while (time_before(jiffies, delay)); /*再延迟 2s*/ unsigned long delay = jiffies + 2*HZ; while (time_before(jiffies, delay));
其中,time_befor()只是一个函数宏,与其对应的还有一个time_after():
#define time_after(a,b) \ (typecheck(unsigned long, a) && \ typecheck(unsigned long, b) && \ ((long)(b) - (long)(a) < 0)) #define time_before(a,b) time_after(b,a)
3、睡眠短延时
3.1 sleep类延时函数
下述函数将使得调用它的进程睡眠参数指定的时间,受系统 HZ 和进程调度的影响,msleep()类似函数的精度是有限的。msleep()、ssleep()不能被打断,而msleep_interruptible()则可以被打断。
void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds);
3.2 schedule类睡眠延时函数
signed long schedule_timeout_interruptible(signed long timeout);signed long schedule_timeout_uninterruptible(signed long timeout)
schedule_timeout()可以使当前任务睡眠指定的jiffies 之后重新被调度执行,它的实现原理是向系统添加一个定时器,在定时器处理函数中唤醒参数对应的进程。上一小节的sleep类函数的底层实现也是调用它实现的:
void msleep(unsigned int msecs)
{ unsigned long timeout = msecs_to_jiffies(msecs) + 1; while (timeout) timeout = schedule_timeout_uninterruptible(timeout);
} unsigned long msleep_interruptible(unsigned int msecs)
{ unsigned long timeout = msecs_to_jiffies(msecs) + 1; while (timeout && !signal_pending(current)) timeout = schedule_timeout_interruptible(timeout); return jiffies_to_msecs(timeout); //返回剩余的延时时间
}signed long _ _sched schedule_timeout_interruptible(signed long timeout)
{ _ _set_current_state(TASK_INTERRUPTIBLE); //置进程状态为 TASK_INTERRUPTIBLEreturn schedule_timeout(timeout);
} signed long _ _sched schedule_timeout_uninterruptible(signed long timeout)
{ _ _set_current_state(TASK_UNINTERRUPTIBLE); //置进程状态为 TASK_UNINTERRUPTIBLEreturn schedule_timeout(timeout);
}
3.3 sleep_on类,在等待队列上睡眠的延时函数
函数可以将当前进程添加到等待队列中,从而在等待队列上睡眠。当超时发生时,进程将被唤醒(后者可以在超时前被打断):
sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout); interruptible_sleep_on_timeout(wait_queue_head_t*q, unsigned long timeout);
Linux内核中的延时函数详解相关推荐
- linux内核中的hook函数详解,linux内核中的hook函数详解
在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的. 先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数 ...
- linux hook 任意内核函数,linux内核中的hook函数详解
在编写linux内核中的网络模块时,用到了钩子函数也就是hook函数.现在来看看linux是如何实现hook函数的. 先介绍一个结构体: struct nf_hook_ops,这个结构体是实现钩子函数 ...
- Linux 内核中RAID5源码详解之守护进程raid5d
Linux 内核中RAID5源码详解之守护进程raid5d 对于一个人,大脑支配着他的一举一动:对于一支部队,指挥中心控制着它的所有活动:同样,对于内核中的RAID5,也需要一个像大脑一样的东西来支配 ...
- 内核中的kmalloc函数详解
一.kmalloc函数详解 #include <linux/slab.h> void *kmalloc(size_t size, int flags); 给 kmalloc 的第一个参数是 ...
- linux内核kconfig objs,linux内核中Kconfig和Makefile 详解
内核源码树的目录下都有两个文档 Kconfig (2.4版本是Config.in)和Makefile.分布到各目录的Kconfig构成了一个分布式的内核配置数据库,每个Kconfig分别描述了所属目录 ...
- linux64位ioremap函数,linux操作系统中的ioremap函数详解
在编写驱动程序的过程中,我们总免不了要使用ioremap函数来将我们的硬件的地址映射到系统的虚拟地址空间. ioramp函数原型: #define ioremap(cookie,size) __ior ...
- 【Linux系统编程】fork()函数详解
00. 目录 文章目录 00. 目录 01. 进程创建函数 02. 父子进程结构 03. 父子进程地址空间 04. 附录 01. 进程创建函数 #include <sys/types.h> ...
- 【Linux系统编程】vfork() 函数详解
00. 目录 文章目录 00. 目录 01. vfork函数 02. fork和vfork区别 03. 父子进程地址空间 04. 附录 01. vfork函数 函数分析 #include <sy ...
- linux系统里route -n不起作用,Linux系统中traceroute命令使用详解
Linux系统中traceroute命令可以追踪到网络数据包的路由途径.下面由学习啦小编为大家整理了linux系统中traceroute命令使用详解,希望对大家有帮助! Linux系统中tracero ...
最新文章
- java keytool 代码_JDK keytool证书工具功能代码解析_java_脚本之家
- 成功解决mxnet-tag\mxnet\src\operator\tensor\./matrix_op-inl.h:189: Using target_shape will be deprecated
- 关于centos6升级python3.6无法使用pip的问题
- .NET CORE(C#) WPF简单菜单MVVM绑定
- datavideo切换台说明书_【新品发布】datavideo SE-650 高清四通道切换台
- linux分割图片软件,桌面应用|5 种拆分 Linux 终端的方法
- 用一个参数化的模型来投影点
- 这个大部分CNS都会用到的技术分析流程大放送......
- 买mac电脑的各个使用阶段:
- PetShop之业务逻辑层设计
- 反射机制在JDBC连接中的使用
- 【转】网络安全-------防止被抓包
- 批标准化 tf.keras.layers.BatchNormalization 参数解析与应用分析
- java 生成Excel开门篇
- win2008 时间同步命令
- 增值税发票识别,智能自动识别
- 面向对象的系统分析(一)-系统分析方法
- 幻14 连不上无线网 网卡掉驱动
- 5G NTN进展简述
- 用户网络接口UNI和网络节点接口NNI