1、為什麼要使用等待隊列?等待隊列就是阻塞型字元裝置驅動的必需品。阻塞型就是說某個裝置可讀或者可寫,但是呢,某個時候這個裝置沒有東西給你讀,但你的應用程式(進程)操作卻要向裝置去讀取資料,那沒辦法,要麼就出錯,要麼就阻塞著在那裡等著要讀取資料。一旦裝置有東西可以給你讀了,進程就可以繼續進行讀操作了。
2、定義並初始化等待隊列。
(1) 定義"等待隊列頭"
wait_queue_head_t my_queue;
(2) 初始化"等待隊列頭"
init_waitqueue_head(&my_queue);
定義和初始化的捷徑:
DECLARE_WAIT_QUEUE_HEAD(my_queue);
3、哪裡去使用等待隊列?在你的操作函數裡。比如讀操作或者寫操作。
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()和wait_event_interruptible()的區別在於後者可以被訊號打斷,而前者不能。加上timeout後的宏意味著阻塞等待的逾時時間,以jiffy為單位,在第三個參數的timeout到達時,不論condition是否滿足,均返回。
4、哪裡喚醒,怎麼喚醒?喚醒的方式要對應等待的事件。
void wake_up(wait_queue_head_t *queue);
void wake_up_interruptible(wait_queue_head_t *queue);
上述操作會喚醒以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_interruptble()只能喚醒處於TASK_INTERRUPTIBLE的進程。
喚醒操作一般是在中斷程式裡面執行的。還要記得condition要賦值為真才能真正喚醒!!
來源:http://markter.blog.163.com/blog/static/173553995201182875330918/