真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

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

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

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

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

}
// 當(dāng)前進程掛載到睡眠隊列p中,p指向隊列頭指針的地址
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為第一個睡眠節(jié)點的地址,即tmp指向第一個睡眠節(jié)點
        頭指針指向當(dāng)前進程,這個版本的實現(xiàn)沒有采用真正鏈表的形式,
        他通過每個進程在棧中的臨時變量形成一個鏈表,每個睡眠的進程,
        在棧里有一個變量指向后面一個睡眠節(jié)點,然后把鏈表的頭指針指向當(dāng)前進程,
        然后切換到其他進程執(zhí)行,當(dāng)被wake_up喚醒的時候,wake_up會喚醒鏈表的第一個
        睡眠節(jié)點,因為第一個節(jié)點里保存了后面一個節(jié)點的地址,所以他喚醒后面一個節(jié)點,
        后面一個節(jié)點以此類推,從而把整個鏈表的節(jié)點喚醒,這里的實現(xiàn)類似nginx的filter,
        即每個模塊保存后面一個節(jié)點的地址,然后把全局指針指向自己。
    */
    tmp = *p;
    *p = current;
    // 不可中斷睡眠只能通過wake_up喚醒,即使有信號也無法喚醒
    current->state = TASK_UNINTERRUPTIBLE;
    schedule();
    // 喚醒后面一個節(jié)點
    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和接收信號喚醒,不可中斷的時候,
    能保證喚醒的時候,是從前往后逐個喚醒,但是可中斷睡眠無法保證這一點,
    因為進程可能被信號喚醒了,所以需要判斷全局指針是否指向了自己,即自己插入
    鏈表后,還有沒有進程也插入了該鏈表
*/
repeat:    current->state = TASK_INTERRUPTIBLE;
    schedule();
    /*
        這里為true,說明是信號喚醒,因為wake_up能保證喚醒的是第一個節(jié)點,
        這里先喚醒鏈表中比當(dāng)前進程后插入鏈表的節(jié)點,有點奇怪,自己被信號喚醒了,
        去喚醒別的進程,自己卻還睡眠
    */
    if (*p && *p != current) {
        (**p).state=0;
        goto repeat;
    }
    // 類似sleep_on的原理
    *p=NULL;
    if (tmp)
        tmp->state=0;
}
// 喚醒隊列中的第一個節(jié)點,并清空鏈表,因為第一個節(jié)點會向后喚醒其他節(jié)點
void wake_up(struct task_struct **p)
{
    if (p && *p) {
        (**p).state=0;
        *p=NULL;
    }
}

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


文章標題:如何進行l(wèi)inux0.11進程睡眠喚醒的原理分析
URL地址:http://weahome.cn/article/ihgccc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部