linux核心的 等待隊列 使用方法,wait_queue_head_t,進程休眠__linux

來源:互聯網
上載者:User

 當你在使用者空間需要讀寫一大片資料的時候,這個就用上了。

 

以下來自:http://www.yuanma.org/data/2006/1207/article_1916.htm 假設我們在 kernel 裡產生一個 buffer,user 可以經由 read,write 等 system call 來讀取或寫資料到這個 buffer 裡。如果有一個 user 寫資料到 buffer 時,此時 buffer 已經滿了。那請問你要如何去處理這種情形呢 ? 第一種,傳給 user 一個錯誤訊息,說 buffer 已經滿了,不能再寫入。第二種,將 user 的要求 block 住, 等有人將 buffer 內容讀走,留出空位時,再讓 user 寫入資料。但問題來了,你要怎麼將 user 的要求 block 住。難道你要用  while ( is_full ); write_to_buffer; 這樣的程式碼嗎? 想想看,如果你這樣做會發生什麼事? 第一,kernel會一直在這個 while 裡執行。第二個,如果 kernel 一直在這個 while 裡執行,表示它沒有辦法去 maintain系統的運作。那此時系統就相當於當掉了。在這裡 is_full 是一個變數,當然,你可以讓 is_full 是一個 function,在這個 function裡會去做別的事讓 kernel 可以運作,那系統就不會當。這是一個方式。還有,你說可以在while裡面把buffer裡的內容讀走,再把is_full的值改了,但是我們會可能把重 要的資料在我們不想被讀的時候被讀走了,那是比較麻煩的,而且很不靈活.如果我們使用 wait_queue 的話, 那程式看起來會比較漂亮,而且也比較讓人瞭解,如下所示:   struct wait_queue_head_t wq; /* global variable */ DECLARE_WAIT_QUEUE_HEAD (wq);   while ( is_full ){ interruptible_sleep_on( &wq ); } write_to_buffer();  

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操作類的)

有好幾個等待和喚醒函數,大家可以慢慢試。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.