3.2.4.2 处理等待队列
DECLARE_WAIT_QUEUE_HEAD用于静态声明一个等待队列的头变量,并初始化lock和task_list分量,init_waitqueue_head用于初始化动态分配的等待队列头变量。
init_waitqueue_entry(q, p)初始化等待队列中的元素(wait_queue_t)
q->flags = 0;
q->task = p;
q->func = default_wake_function;
default_wake_function是TRy_to_wake_up()函数的包裹函数
另外,DEFINE_WAIT宏用于声明一个wait_queue_t变量,并使用当前CPU中运行的进程的进程描述符初始化task分量,以及使用autoremove_wake_function初始化func函数指针。
autoremove_wake_function函数调用default_wake_function来唤醒正在睡眠的进程,然后将被唤醒的进程从等待队列中删除。
一个wait_queue_t元素被定义后,即被插入到等待队列中,add_wait_queue函数将一个非独占资源进程插入到等待队列的头部,add_wait_queue_exclusive函数将一个独占资源进程插入到等待队列的尾部,
remove_wait_queue将一个进程从等待队列中移除,waitqueue_active检查一个给定的等待队列是否为空。
当一个进程希望等待一个特定的条件时,可以调用下列几个函数:
1、sleep_on(),作用于当前进程:
void sleep_on(wait_queue_head_t *wq)
{
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
current->state = TASK_UNINTERRUPTIBLE;
add_wait_queue(wq,&wait); /* wq points to the wait queue head */
schedule( );
remove_wait_queue(wq, &wait);
}
该函数将当前进程的状态设置为TASK_UNINTERRUPTIBLE,并将其插入到某个等待队列中,然后调用调度器,将CPU控制权转移到其他进程中,
当该睡眠进程被唤醒后,调度器重新回到sleep_on的执行,然后将该进程从等待队列中移除。
2、interruptible_sleep_on(),与sleep_on()相同,除了它将当前进程设置为TASK_INTERRUPTIBLE,这样的话该进程也可以被信号唤醒了。
3、sleep_on_timeout()和interruptible_sleep_on_timeout(),与前面的相似,但他们也允许调用者设置一个时间间隔,当达到时间间隔后,进程会被内核唤醒,通过调用schedule_timeout实现。
4、prepare_to_wait()、prepare_to_wait_exclusive()、finish_wait(),2.6内核引入,提供了另外一种方式使当前进程进入等待队列,典型用法如下:
DEFINE_WAIT(wait);
prepare_to_wait_exclusive(&wq, &wait, TASK_INTERRUPTIBLE);
/* wq is the head of the wait queue */
...
if (!condition)
schedule();
finish_wait(&wq, &wait);
这两个函数都是通过第三个参数将进程状态设置,然后设置独占标志,然后插入到等待队列中。当条件成立时,就会执行finish_wait函数,该函数将当前进程设置为TASK_RUNNING,并且从等待队列中移除。
5、The wait_event and wait_event_interruptible macros put the calling process to sleep on a wait queue until a given condition is verified. For instance, the wait_event(wq,condition) macro essentially yields the following fragment:
DEFINE_WAIT(_ _wait);
for (;;) {
prepare_to_wait(&wq, &_ _wait, TASK_UNINTERRUPTIBLE);
if (condition)
break;
schedule( );
}
finish_wait(&wq, &_ _wait);
阅读(1253) | 评论(0) | 转发(1) |