色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

Hi,歡迎來到嵌入式培訓高端品牌 - 華清遠見教育科技集團<北京總部官網>,專注嵌入式工程師培養15年!
當前位置: > 華清遠見教育科技集團 > 嵌入式學習 > 講師博文 > _wait_event 具體實現過程
_wait_event 具體實現過程
時間:2017-01-06作者:華清遠見

#define __wait_event(wq, condition) 
        do { 
        DEFINE_WAIT(__wait);

for (;;) { 
        prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); 
        if (condition) 
        break; 
        schedule(); 
        } 
        finish_wait(&wq, &__wait); 
        } while (0)

在DEFINE_WAIT(__wait)中
        #define DEFINE_WAIT(name) 
        wait_queue_t name = { 
        .task = current, 
        .func = autoremove_wake_function, 
        .task_list = { .next = &(name).task_list, 
        .prev = &(name).task_list, 
        }, 
        } 
        的autoremove_wake_function:

int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) 
        { 
        int ret = default_wake_function(wait, mode, sync, key);

if (ret) 
        list_del_init(&wait->task_list); //注意,等待節點在這里被摘下,并設為空 
        return ret; 
        }

prepare_to_wait()和finish_wait()并不是進程睡眠的地方,進程睡眠的地方是schedule()。

prepare_to_wait()只是進行一些鏈表的操作,以確保自己在等待隊列中,不會漏掉事件。

進程在確信自己已經在隊列中后,再次檢查條件, 這里,如果不檢查,可能條件已經滿足,直接去睡眠的話,可能再也沒有人來喚醒它了。

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

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

當條件滿足后,會有一個人(或者是其他進程,或者內核本身,等等)來喚醒某個等待隊列上的進程。

具體是喚醒全部等待隊列中的所有進程,還是只喚醒第一個進程,完全取決于該喚醒者, 等待在隊列中的睡眠進程是無能為力的,與它們是沒有關系的(呵呵,確切說,有一點關系)。

總是喚醒所有等待該事件的進程并不一定是合適的。比如考慮這樣一種情況:如果隊列中的多個進程等待的資源是要互斥訪問的,一定時間內只允許一個進程去訪問的話,這時候,只需要喚醒一個進程就可以了,其他進程繼續睡眠。如果喚醒所有的進程,終也只有一個進程獲得該資源,其他進程讓需返回睡眠。

因此,等待隊列中的睡眠進程可被劃分為互斥、非互斥進程。

互斥進程:等待的資源是互斥訪問的;互斥進程由內核有選擇的喚醒,等待隊列項的flag字段為1;
        非互斥進程:等待的資源是可多進程同時訪問的。非互斥進程在事件發生時,總是被內核喚醒,等待隊列元素的flag字段為0。

喚醒者通常調用__wake_up_common(),這樣,依次取下等待隊列中的__wait_queue_t結構, 調用該睡眠進程設置的func函數,即這里的autoremove_wake_function(), 將該進程的狀態重新設置為RUNNING。

注意,此時該睡眠進程并不會立刻執行,只有等到下次調度的時候,該進程才有機會運行, 即醒來了。醒來是從schedule()回來,繼續運行__wait_event()

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

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

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
主站蜘蛛池模板: av小次郎收藏家 | 精品久久久无码人妻字幂 | 国产成年无码久久久免费 | 夜夜天天噜狠狠爱2019 | 在线精品一卡乱码免费 | 波多野结AV衣东京热无码专区 | 后入内射无码人妻一区 | 久久99热精品免费观看 | 亚洲国产熟妇无码一区二区 | 婷婷综合亚洲爱久久 | 亚洲精品国产字幕久久麻豆 | 涩涩涩涩涩涩涩涩涩 | 成人免费视频源码网站 | 手机看免费毛片的网站 | 成年美女黄网站色大片免费软件看 | 亚洲 a v无 码免 费 成 人 a v | 初尝人妻少妇中文字幕 | 国产成人无码aⅴ片在线观看导航 | 亚洲精品无码一区二区三天美 | 性生交大片免费看l | 无码人妻精品一区二区三区欧美 | 女狠狠噜天天噜日日噜 | 久久99亚洲含羞草影院 | 无码人妻熟妇AV又粗又大 | 被医生绑在妇科椅调教 | 欧美老熟妇乱子伦视频 | 人妻有码中文字幕 | 亚洲婷婷五月综合狠狠 | 麻豆一区产品精品蜜桃的广告语 | 久久久亚洲欧洲日产国产成人无码 | 亚洲国产精品无码中文在线 | 日本A级C片免费看三区 | 无码国产精品亚洲а∨天堂dvd | 国产国拍亚洲精品av在线 | 欧美色倩网站大全免费 | asian日本java少妇乱子另类 | 一个人免费观看视频www | 日日鲁鲁鲁夜夜爽爽狠狠 | 在线激情av| 亚洲AV成人中文无码专区 | 无码人妻一区二区三区线 |