久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

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

#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); 
 &nbsp;      } 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; 
      &nbsp; }

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

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

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

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

注意,這里,該進程(cheng)自己(ji)已(yi)經無能為(wei)力了,因為(wei)它自己(ji)已(yi)經不(bu)可能運行了。 只有(you)等待他人來喚(huan)醒了。

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

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

總是喚(huan)醒所有等待該(gai)事件(jian)的進(jin)(jin)程(cheng)并不一(yi)(yi)(yi)定(ding)(ding)是合適的。比如考慮(lv)這(zhe)(zhe)樣一(yi)(yi)(yi)種(zhong)情況:如果(guo)(guo)隊(dui)列中(zhong)的多個(ge)(ge)進(jin)(jin)程(cheng)等待的資(zi)源(yuan)是要互斥(chi)訪問的,一(yi)(yi)(yi)定(ding)(ding)時(shi)(shi)間內只允(yun)許一(yi)(yi)(yi)個(ge)(ge)進(jin)(jin)程(cheng)去訪問的話,這(zhe)(zhe)時(shi)(shi)候,只需要喚(huan)醒一(yi)(yi)(yi)個(ge)(ge)進(jin)(jin)程(cheng)就(jiu)可以了(le),其他(ta)(ta)進(jin)(jin)程(cheng)繼續睡眠(mian)(mian)。如果(guo)(guo)喚(huan)醒所有的進(jin)(jin)程(cheng),終(zhong)也只有一(yi)(yi)(yi)個(ge)(ge)進(jin)(jin)程(cheng)獲得(de)該(gai)資(zi)源(yuan),其他(ta)(ta)進(jin)(jin)程(cheng)讓需返回(hui)睡眠(mian)(mian)。

因此,等待隊列中的睡眠進程(cheng)可(ke)被劃分(fen)為互斥(chi)、非(fei)互斥(chi)進程(cheng)。

互斥進程:等待的資源是互斥訪問的;互斥進程由內核有選擇的喚醒,等待隊列項的flag字段為1;
  &nbsp;     非互(hu)斥進(jin)(jin)程:等待(dai)的(de)資源是(shi)可多進(jin)(jin)程同(tong)時訪問的(de)。非互(hu)斥進(jin)(jin)程在事件發生(sheng)時,總是(shi)被內核喚醒(xing),等待(dai)隊列元(yuan)素的(de)flag字段為0。

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

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

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

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

發表評論
評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)