_wait_event 具體實現過程

來源:互聯網
上載者:User

來自:http://www.linuxforum.net/forum/showthreaded.php?Board=linuxK&Number=572220

是不是當前進程要等待某個condition,然後就把它加到這個等待這個condition的wq中
_wait_event是當前進程調用它,也就是在宏DEFINE_WAIT(_wait)中的_wait就是把當前進程設定成_wait加到等待隊列裡,

以上基本正確


如果condition發生,是這個進程被喚醒設定成running而不是整個等待隊列wq被喚醒?
如果conditon沒有發生,還在prepare_to_wait裡,這裡保證了_wait不會被第二次加到等待隊列中,但是第一次迴圈是加入了。finish_wait是將_wait移除。

那麼在DEFINE_WAIT中的func設定成autoremove_wake_function意義何在?

prepare_to_wait()和finish_wait()並不是進程睡眠的地方,進程睡眠的地方是schedule().
prepare_to_wait()只是進行一些鏈表的操作,以確保自己在等待隊列中,不會漏掉事件。
進程在確信自己已經在隊列中後,再次檢查條件,
這裡,如果不檢查,可能條件已經滿足,直接去睡眠的話,可能再也沒有人來喚醒它了。

然後,如果條件不滿足,就調用schedule()去睡眠,
這裡,進程的狀態在prepare_to_wait()裡設定為TASK_UNINTERRUPTIBLE,
所以,以後調度時就看不到該進程了,因此,該進程將沒有機會運行,這就是睡眠。

注意,這裡,該進程自己已經無能為力了,因為它自己已經不可能運行了。
只有等待他人來喚醒了。

當條件滿足後,會有一個人(或者是其他進程,或者核心本身,等等)來喚醒某個等待隊列上的進程。
具體是喚醒全部等待隊列中的所有進程,還是只喚醒第一個進程,完全取決於該喚醒者,
等待在隊列中的睡眠進程是無能為力的,與它們是沒有關係的(呵呵,確切說,有一點關係)。

喚醒者通常調用__wake_up_common(),這樣,依次取下等待隊列中的__wait_queue_t結構,
調用該睡眠進程設定的func函數,即這裡的autoremove_wake_function(),
將該進程的狀態重新設定為RUNNING,
注意,此時該睡眠進程並不會立刻執行,只有等到下次調度的時候,該進程才有機會運行,
即醒來了。醒來是從schedule()回來,繼續運行__wait_event()

總結一下,
睡眠是自己設定好進程狀態(TASK_UNINTERRUPTIBLE,等等),加入等待隊列,
並調用schedule()去睡眠。

睡眠是自己的動作。

喚醒是別人發現條件滿足,調用__wake_up_common(),將睡眠進程從等待隊列取下,
調用該睡眠進程設定的喚醒func,重新設定該睡眠進程為RUNNING。
從而可以在下次調度時運行。

喚醒是別人的動作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.