wake_up()与wait_event()或者wait_event_timeout成对使用,
wake_up_intteruptible()与wait_event_intteruptible()或者wait_event_intteruptible_timeout()成对使用。
在 Linux 中, 一个等待队列由一个"等待队列头"来管理, 一个 wait_queue_head_t 类型的结构, 定义在中. 一个等待队列头可被定义和初始化, 使用:
DECLARE_WAIT_QUEUE_HEAD(name);
或者动态地, 如下:
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);
1、简单睡眠:
Linux 内核中睡眠的最简单方式是一个宏定义, 称为 wait_event(有几个变体); 它结合了处理睡眠的细节和进程在等待的条件的检查. wait_event 的形式是:
wait_event(queue, condition)
wait_event_interruptible(queue, condition)
wait_event_timeout(queue, condition, timeout)
wait_event_interruptible_timeout(queue, condition, timeout)
这些东西如何使用?queue 是等待队列头,condition 是条件,如果调用 wait_event 前 condition == 0 ,则调用 wait_event 之后,当前进程就会休眠
wait_event:
将当前进程的状态设置为 TASK_UNINTERRUPTIBLE ,然后 schedule()
wait_event_interruptible:
TASK_INTERRUPTIBLE ,然后 schedule()
wait_event_timeout:
TASK_UNINTERRUPTIBLE ,然后 schedule_timeout()
wait_event_interruptible_timeout:
TASK_INTERRUPTIBLE , 然后 schedule_timeout()
TASK_INTERRUPTIBLE 与 TASK_UNINTERRUPTIBLE 区别在于:
它的休眠是否会被信号打断,别的进程发来一个信号比如 kill ,TASK_INTERRUPTIBLE 就会醒来去处理。然而 TASK_UNINTERRUPTIBLE 不会。schedule(),进程调度,而schedule_timeout()进行调度之后,一定时间后自动唤醒。
对应于不同的进程状态,使用不同的唤醒函数:
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
唤醒时很有意思,比如你调用 wake_up 去唤醒一个使用 wait_event 等,进入休眠的进程,唤醒之后,它会判断 condition 是否为真,如果还是假的继续睡眠。
2、手动睡眠:
DECLARE_WAITQUEUE(name, tsk) 创建一个等待队列:
tsk一般为当前进行current. 这个宏定义并初始化一个名为name的等待队列.
将等待队列头 加入/移除 等待队列:
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
设置进程状态:
set_current_state(TASK_INTERRUPTIBLE) 等
进程调度:
schedule() 或者 schedule_timeout()