在Linux驱动程序中,可以使用等待队列(Wait Queue)来实现阻塞进程的唤醒。
1.定义“等待队列头部”
wait_queue_head_t my_queue;
wait_queue_head_t是__wait_queue_head结构体的一个typedef。
2.初始化“等待队列头部”
init_waitqueue_head(&my_queue);
而下面的DECLARE_WAIT_QUEUE_HEAD()宏可以作为定义并初始化等待队列头部的“快捷方式”。
DECLARE_WAIT_QUEUE_HEAD (name)
3.定义等待队列元素
DECLARE_WAITQUEUE(name, tsk)
该宏用于定义并初始化一个名为name的等待队列元素。
4.添加/移除等待队列
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
add_wait_queue()用于将等待队列元素wait添加到等待队列头部q指向的双向链表中,而
remove_wait_queue()用于将等待队列元素wait从由q头部指向的链表中移除。
5.等待事件
wait_event(queue, condition) wait_event_interruptible(queue, condition) wait_event_timeout(queue, condition, timeout) wait_event_interruptible_timeout(queue, condition, timeout)
等待第1个参数queue作为等待队列头部的队列被唤醒,而且第2个参数condition必须满足,否则继续
阻塞。wait_event()和wait_event_interruptible()的区别在于后者可以被信号打断,而前者不能。加上
_timeout后的宏意味着阻塞等待的超时时间,以jiffy为单位,在第3个参数的timeout到达时,不论condition
是否满足,均返回。
函数原型:
@condition:当是0时候进程进入休眠,是1的时候继续往下运行
6.唤醒队列
void wake_up(wait_queue_head_t *queue); void wake_up_interruptible(wait_queue_head_t *queue);
wake_up()应该与wait_event()或wait_event_timeout()成对使用,而wake_up_interruptible()则
应与wait_event_interruptible()或wait_event_interruptible_timeout()成对使用。wake_up()可唤醒处于
TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE的进程,而wake_up_interruptible()只能唤醒处于
TASK_INTERRUPTIBLE的进程。