_wait_event 具體實現過程
時(shi)間(jian):2017-01-06作(zuo)者:華(hua)清遠見(jian)
#define __wait_event(wq, condition)
for (;;) {
在DEFINE_WAIT(__wait)中
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
if (ret) 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; 喚醒者通常(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)動作。
相關資訊
發表評論
|