如何進(jìn)行l(wèi)inux0.11進(jìn)程睡眠喚醒的原理分析

如何進(jìn)行l(wèi)inux0.11進(jìn)程睡眠喚醒的原理分析,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

目前創(chuàng)新互聯(lián)公司已為1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、澤州網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

進(jìn)程的睡眠是通過調(diào)用sleep_on函數(shù),該函數(shù)修改了進(jìn)程的狀態(tài)并且通過schedule函數(shù)切換到其他進(jìn)程執(zhí)行,從而實(shí)現(xiàn)進(jìn)程的掛起,TASK_UNINTERRUPTIBLE狀態(tài)的進(jìn)程只能被wake_up函數(shù)喚醒。TASK_INTERRUPTIBLE狀態(tài)的進(jìn)程可以被wake_up和信號(hào)喚醒。喚醒的時(shí)候也是通過修改進(jìn)程的狀態(tài)為可運(yùn)行,然后等待下一次進(jìn)程調(diào)度,被喚醒的進(jìn)程不一定馬上得到執(zhí)行。

}
// 當(dāng)前進(jìn)程掛載到睡眠隊(duì)列p中,p指向隊(duì)列頭指針的地址
void sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;

    if (!p)
        return;
    if (current == &(init_task.task))
        panic("task[0] trying to sleep");
    /*
        *p為第一個(gè)睡眠節(jié)點(diǎn)的地址,即tmp指向第一個(gè)睡眠節(jié)點(diǎn)
        頭指針指向當(dāng)前進(jìn)程,這個(gè)版本的實(shí)現(xiàn)沒有采用真正鏈表的形式,
        他通過每個(gè)進(jìn)程在棧中的臨時(shí)變量形成一個(gè)鏈表,每個(gè)睡眠的進(jìn)程,
        在棧里有一個(gè)變量指向后面一個(gè)睡眠節(jié)點(diǎn),然后把鏈表的頭指針指向當(dāng)前進(jìn)程,
        然后切換到其他進(jìn)程執(zhí)行,當(dāng)被wake_up喚醒的時(shí)候,wake_up會(huì)喚醒鏈表的第一個(gè)
        睡眠節(jié)點(diǎn),因?yàn)榈谝粋€(gè)節(jié)點(diǎn)里保存了后面一個(gè)節(jié)點(diǎn)的地址,所以他喚醒后面一個(gè)節(jié)點(diǎn),
        后面一個(gè)節(jié)點(diǎn)以此類推,從而把整個(gè)鏈表的節(jié)點(diǎn)喚醒,這里的實(shí)現(xiàn)類似nginx的filter,
        即每個(gè)模塊保存后面一個(gè)節(jié)點(diǎn)的地址,然后把全局指針指向自己。
    */
    tmp = *p;
    *p = current;
    // 不可中斷睡眠只能通過wake_up喚醒,即使有信號(hào)也無法喚醒
    current->state = TASK_UNINTERRUPTIBLE;
    schedule();
    // 喚醒后面一個(gè)節(jié)點(diǎn)
    if (tmp)
        tmp->state=0;
}

void interruptible_sleep_on(struct task_struct **p)
{
    struct task_struct *tmp;

    if (!p)
        return;
    if (current == &(init_task.task))
        panic("task[0] trying to sleep");
    tmp=*p;
    *p=current;
/*
    可中斷地睡眠,可以通過wake_up和接收信號(hào)喚醒,不可中斷的時(shí)候,
    能保證喚醒的時(shí)候,是從前往后逐個(gè)喚醒,但是可中斷睡眠無法保證這一點(diǎn),
    因?yàn)檫M(jìn)程可能被信號(hào)喚醒了,所以需要判斷全局指針是否指向了自己,即自己插入
    鏈表后,還有沒有進(jìn)程也插入了該鏈表
*/
repeat:    current->state = TASK_INTERRUPTIBLE;
    schedule();
    /*
        這里為true,說明是信號(hào)喚醒,因?yàn)閣ake_up能保證喚醒的是第一個(gè)節(jié)點(diǎn),
        這里先喚醒鏈表中比當(dāng)前進(jìn)程后插入鏈表的節(jié)點(diǎn),有點(diǎn)奇怪,自己被信號(hào)喚醒了,
        去喚醒別的進(jìn)程,自己卻還睡眠
    */
    if (*p && *p != current) {
        (**p).state=0;
        goto repeat;
    }
    // 類似sleep_on的原理
    *p=NULL;
    if (tmp)
        tmp->state=0;
}
// 喚醒隊(duì)列中的第一個(gè)節(jié)點(diǎn),并清空鏈表,因?yàn)榈谝粋€(gè)節(jié)點(diǎn)會(huì)向后喚醒其他節(jié)點(diǎn)
void wake_up(struct task_struct **p)
{
    if (p && *p) {
        (**p).state=0;
        *p=NULL;
    }
}

關(guān)于如何進(jìn)行l(wèi)inux0.11進(jìn)程睡眠喚醒的原理分析問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

文章名稱:如何進(jìn)行l(wèi)inux0.11進(jìn)程睡眠喚醒的原理分析
文章路徑:http://muchs.cn/article22/ihgccc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、搜索引擎優(yōu)化、企業(yè)建站、云服務(wù)器用戶體驗(yàn)、

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)