定义等待队列头:
wait_queue_head_t queue_head;
初始化等待对列头:
init_waitqueue_head(queue_head);
还一种就是利用宏定义直接完成上面两步骤:
DECLARE_WAIT_QUEUE_HEAD(queue_head);//定义和初始化都完成,其好处是方便,但是不便于你封装一个queue_head的等待队列头到你自己定义的结构体中。
接下来就是定义等待队列头中的队列项:
DECLARE_WAITQUEUE(name,tsk);name为要定义的队列项变量的名字,第二个参数一般就是current来表示这个这个队列项同当前运行这段程序的进程关联。
再就是将队列项name用add_wait_queue(&queue_head, &name)加入到等待队列头中,根据需要通过set_current_state(state)来设置进程的状态state可以是 TASK_RUNNING,TASK_INTERRUPTIBLE 和TASK_UNINTERRUPTIBLE等。
再接着就是根据条件调用schedule()来挂起进程。在调用了schedule()代码后面就要判断进程是怎么被唤醒的,到底是信号唤醒还是由于条件满足而被正常唤醒的(既然代码能够运行到schedule之后表明进程已经被唤醒了,唤醒有可能是在别的地方由于操作条件满足而被唤醒,也有可能是设置了TASK_INTERRUPTIBLE而被信号唤醒)。如果是正常唤醒就进行满足条件操作的代码,否则由于信号唤醒而返回错误。最后返回前还要remove_wait_queue()来移除队列项。
在要唤醒等待队列的地方要调用wake_up来唤醒队列头上的队列项。
另外一种是用等待队列的方法就是,定义和初始化等待对列头后直接是用wait_event和wake_up来操作,但是wait_even(wq,condition)只是简单判断condition是真或假来等待,太过简单了一点。