内核延迟操作
内核延迟分为长延迟和段延迟, 长延时一般以jiffies为单位, 短延时则以jiffy为单位, 对于不同延迟应该选用不同的实现方法。
长延迟一般通过硬件时钟滴答来实现, 对于长延迟,可以使用等待队列机制
// 忙等待delay, 常用于不能调度的上下文,例如 中断, 当使用下列函数实现延时,cpu不调度,仍然停留在该进程上做无用功,浪费cpu时间
内核延迟分为长延迟和段延迟, 长延时一般以jiffies为单位, 短延时则以jiffy为单位, 对于不同延迟应该选用不同的实现方法。
长延迟一般通过硬件时钟滴答来实现, 对于长延迟,可以使用等待队列机制
#include <linux/wait.h>
long wait_event_timeout(wait_queue_head_t, condition, long timeout); // 休眠时不可中断
long wait_event_interruptible_timeout(wait_queue_head_t, condition, long timeout); // 可被信号中断
#include <linux/sched.h>
signed long schedule_timeout(signed long timeout); // 主动放弃cpu timeout时间
应用场景
// 等待队列
wait_queue_head_t wait; // 定义等待队列
init_waitqueue_head(&wait); // 初始化
wait_event_interruptible_timeout(wait, 0, HZ); // 调度,延时
// 主动放弃cpu延时
set_current_state(TASK_INTERRUPTIBLE); // 设置当前进程状态
schedule_timeout(HZ); // 调度,延时
短延迟不依赖时钟滴答来实现的, 使用软件循环来实现的机制
// 忙等待delay, 常用于不能调度的上下文,例如 中断, 当使用下列函数实现延时,cpu不调度,仍然停留在该进程上做无用功,浪费cpu时间
#include <linux/delay.h>
void ndelay(unsigned long nsecs); // 纳秒级
void udelay(unsigned long usecs); // 微秒级
void mdelay(unsigned long msecs); // 毫秒级
// 内核提供sleep接口,是的调用者能够延时的时候主动让出cpu,实现休眠
void msleep(unsigned int millisecs); // 毫秒级,不可中断
unsigned long msleep_interruptible(unsigned int millisecs); // 毫秒级,可中断
void ssleep(unsigned int seconds); // 秒级,不可中断
ps. 如果能容忍比所请求更长的延迟,则应使用"schedule_timeout"、"ssleep"