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嘛,就是分享心得。
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操作類的)
有好幾個等待和喚醒函數,大家可以慢慢試。