interruptible_sleep_on( &wq ) 是用来将目前的 process,也就是要求写资料到buffer 的 process放到 wq 这个 wait_queue 里。在 interruptible_sleep_on 里,则是最后会呼叫 schedule() 来做 schedule 的动作,谁调用了schedule谁就趴下,让别人去运行,醒来就原地起来,执行schedule()后的代码。那那个调用了schedule的家伙什么 醒过来呢?这时候就需要用到另一个函数了wake_up_interruptible()了。
以下来自:http://tauruspdj.blog.163.com/blog/static/4312500620090794030998/
linux中最简单的休眠方式是下面的宏,
wait_event(queue, condition) /* 进程将被置于非中断休眠(uninterruptible sleep)*/
wait_event_interruptible(queue, condition) /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/
wait_event_timeout(queue, condition, timeout) /*等待限定时间jiffy,condition满足其一返回0*/
wait_event_interruptible_timeout(queue, condition, timeout)
queue是等待队列头,传值方式
condition是任意一个布尔表达式,在休眠前后多次对condition求值,为真则唤醒
唤醒进程的基本函数是wake_up
void wake_up(wait_queue_head_t *queue); /*唤醒等待在给定queue上的所有进程*/
void wake_up_interruptible(wait_queue_head_t *queue);
实践中,一般是wait_event和 wake_up, wait_event_interruptible和 wake_up_interruptible 成对使用。
【补充】其实看了那么多,他们也没有给个立即可用的步骤,写blog嘛,就是分享心得。我基于2.6.24总结一下,希望对大家有帮助:
1、定义:wait_queue_head_t my_queue;
2、初始化 init_waitqueue_head(&my_queue);
3、在一个函数里面等待:wait_event(queue, condition) ;(别在中断里面搞)
4、在另一个函数里面唤醒:wake_up(wait_queue_head_t *queue); (这个可以在中断调用,去唤醒别的进程,特别是dma操作类的)
有好几个等待和唤醒函数,大家可以慢慢试。