mooc课程精选,成品人片观看入口众乐乐,久久久久人妻一区精品性色av,苍兰诀大结局是什么,白丝美女被狂躁免费视频网站

Hi,歡迎來(lái)到嵌入式培訓(xùn)高端品牌 - 華清遠(yuǎn)見(jiàn)教育科技集團(tuán)<北京總部官網(wǎng)>,專注嵌入式工程師培養(yǎng)15年!
當(dāng)前位置: > 華清遠(yuǎn)見(jiàn)教育科技集團(tuán) > 嵌入式學(xué)習(xí) > 講師博文 > _wait_event 具體實(shí)現(xiàn)過(guò)程
_wait_event 具體實(shí)現(xiàn)過(guò)程
時(shí)間:2017-01-06作者:華清遠(yuǎn)見(jiàn)

#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); //注意,等待節(jié)點(diǎn)在這里被摘下,并設(shè)為空 
        return ret; 
        }

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

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

進(jìn)程在確信自己已經(jīng)在隊(duì)列中后,再次檢查條件, 這里,如果不檢查,可能條件已經(jīng)滿足,直接去睡眠的話,可能再也沒(méi)有人來(lái)喚醒它了。

然后,如果條件不滿足,就調(diào)用schedule()去睡眠,這里,進(jìn)程的狀態(tài)在prepare_to_wait()里設(shè)置為TASK_UNINTERRUPTIBLE, 所以,以后調(diào)度時(shí)就看不到該進(jìn)程了,因此,該進(jìn)程將沒(méi)有機(jī)會(huì)運(yùn)行,這就是睡眠。

注意,這里,該進(jìn)程自己已經(jīng)無(wú)能為力了,因?yàn)樗约阂呀?jīng)不可能運(yùn)行了。 只有等待他人來(lái)喚醒了。

當(dāng)條件滿足后,會(huì)有一個(gè)人(或者是其他進(jìn)程,或者內(nèi)核本身,等等)來(lái)喚醒某個(gè)等待隊(duì)列上的進(jìn)程。

具體是喚醒全部等待隊(duì)列中的所有進(jìn)程,還是只喚醒第一個(gè)進(jìn)程,完全取決于該喚醒者, 等待在隊(duì)列中的睡眠進(jìn)程是無(wú)能為力的,與它們是沒(méi)有關(guān)系的(呵呵,確切說(shuō),有一點(diǎn)關(guān)系)。

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

因此,等待隊(duì)列中的睡眠進(jìn)程可被劃分為互斥、非互斥進(jìn)程。

互斥進(jìn)程:等待的資源是互斥訪問(wèn)的;互斥進(jìn)程由內(nèi)核有選擇的喚醒,等待隊(duì)列項(xiàng)的flag字段為1;
        非互斥進(jìn)程:等待的資源是可多進(jìn)程同時(shí)訪問(wèn)的。非互斥進(jìn)程在事件發(fā)生時(shí),總是被內(nèi)核喚醒,等待隊(duì)列元素的flag字段為0。

喚醒者通常調(diào)用__wake_up_common(),這樣,依次取下等待隊(duì)列中的__wait_queue_t結(jié)構(gòu), 調(diào)用該睡眠進(jìn)程設(shè)置的func函數(shù),即這里的autoremove_wake_function(), 將該進(jìn)程的狀態(tài)重新設(shè)置為RUNNING。

注意,此時(shí)該睡眠進(jìn)程并不會(huì)立刻執(zhí)行,只有等到下次調(diào)度的時(shí)候,該進(jìn)程才有機(jī)會(huì)運(yùn)行, 即醒來(lái)了。醒來(lái)是從schedule()回來(lái),繼續(xù)運(yùn)行__wait_event()

總結(jié)一下, 睡眠是自己設(shè)置好進(jìn)程狀態(tài)(TASK_UNINTERRUPTIBLE,等等),加入等待隊(duì)列, 并調(diào)用schedule()去睡眠。 睡眠是自己的動(dòng)作。

喚醒是別人發(fā)現(xiàn)條件滿足,調(diào)用__wake_up_common(),將睡眠進(jìn)程從等待隊(duì)列取下, 調(diào)用該睡眠進(jìn)程設(shè)置的喚醒func,重新設(shè)置該睡眠進(jìn)程為RUNNING。 從而可以在下次調(diào)度時(shí)運(yùn)行。 喚醒是別人的動(dòng)作。

發(fā)表評(píng)論
評(píng)論列表(網(wǎng)友評(píng)論僅供網(wǎng)友表達(dá)個(gè)人看法,并不表明本站同意其觀點(diǎn)或證實(shí)其描述)