使用方式:
| set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(2*HZ); /* 睡2秒 */ |
进程经过2秒后会被唤醒。如果不希望被用户空间打断,可以将进程状态设置为TASK_UNINTERRUPTIBLE。
| msleep ssleep // 秒 |
(3)等待队列
使用等待队列也可以实现长延迟。
在延迟期间,当前进程在等待队列中睡眠。
进程在睡眠时,需要根据所等待的事件链接到某一个等待队列。
a.声明等待队列
等待队列实际上就是一个进程链表,链表中包含了等待某个特定事件的所有进程。
| #include <linux/wait.h> struct __wait_queue_head { spinlock_t lock; struct list_head task_list; }; typedef struct __wait_queue_head wait_queue_head_t; |
要想把进程加入等待队列,驱动首先要在模块中声明一个等待队列头,并将它初始化。
静态初始化
| DECLARE_WAIT_QUEUE_HEAD(name); |
动态初始化
| wait_queue_head_t my_queue; init_waitqueue_head(&my_queue); |
b.等待函数
进程通过调用下面函数可以在某个等待队列中休眠固定的时间:
| #include <linux/wait.h> long wait_event_timeout(wait_queue_head_t q,condition, long timeout); long wait_event_interruptible_timeout(wait_queue_head_t q, condition, long timeout); |
调用这两个函数后,进程会在给定的等待队列q上休眠,但会在超时(timeout)到期时返回。
如果超时到期,则返回0,如果进程被其他事件唤醒,则返回剩余的时间数。
如果没有等待条件,则将condition设为0
使用方式:
| wait_queue_head_t wait; init_waitqueue_head(&wait); wait_event_interruptible_timeout(wait, 0, 2*HZ); /*当前进程在等待队列wait中睡2秒 */ |
(4)内核定时器
还有一种将任务延迟执行的方法是采用内核定时器。与前面几种延迟方法不同,内核定时器并不会阻塞当前进程,启动一个内核定时器只是声明了要在未来的某个时刻执行一项任务,当前进程仍然继续执行。不要用定时器完成硬实时任务
定时器由结构timer_list表示,定义在<linux/timer.h>
| struct timer_list{ struct list_head entry; /* 定时器链表 */ unsigned long expires; /* 以jiffies为单位的定时值 */ spinlock_t lock; void(*function)(unsigned long); /* 定时器处理函数 */ unsigned long data; /* 传给定时器处理函数的参数 */ } |
内核在<linux/timer.h>中提供了一系列管理定时器的接口。
a.创建定时器
struct timer_list my_timer;
b.初始化定时器
| init_timer(&my_timer); /* 填充数据结构 */ my_timer.expires = jiffies + delay; my_timer.data = 0; my_timer.function = my_function; /*定时器到期时调用的函数*/ |








