前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux0.11进程睡眠唤醒原理分析

linux0.11进程睡眠唤醒原理分析

作者头像
theanarkh
发布2019-04-24 11:03:19
2.3K0
发布2019-04-24 11:03:19
举报
文章被收录于专栏:原创分享

进程的睡眠是通过调用sleep_on函数,该函数修改了进程的状态并且通过schedule函数切换到其他进程执行,从而实现进程的挂起,TASK_UNINTERRUPTIBLE状态的进程只能被wake_up函数唤醒。TASK_INTERRUPTIBLE状态的进程可以被wake_up和信号唤醒。唤醒的时候也是通过修改进程的状态为可运行,然后等待下一次进程调度,被唤醒的进程不一定马上得到执行。

代码语言:javascript
复制
}
// 当前进程挂载到睡眠队列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为第一个睡眠节点的地址,即tmp指向第一个睡眠节点
        头指针指向当前进程,这个版本的实现没有采用真正链表的形式,
        他通过每个进程在栈中的临时变量形成一个链表,每个睡眠的进程,
        在栈里有一个变量指向后面一个睡眠节点,然后把链表的头指针指向当前进程,
        然后切换到其他进程执行,当被wake_up唤醒的时候,wake_up会唤醒链表的第一个
        睡眠节点,因为第一个节点里保存了后面一个节点的地址,所以他唤醒后面一个节点,
        后面一个节点以此类推,从而把整个链表的节点唤醒,这里的实现类似nginx的filter,
        即每个模块保存后面一个节点的地址,然后把全局指针指向自己。
    */
    tmp = *p;
    *p = current;
    // 不可中断睡眠只能通过wake_up唤醒,即使有信号也无法唤醒
    current->state = TASK_UNINTERRUPTIBLE;
    schedule();
    // 唤醒后面一个节点
    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能保证唤醒的是第一个节点,
        这里先唤醒链表中比当前进程后插入链表的节点,有点奇怪,自己被信号唤醒了,
        去唤醒别的进程,自己却还睡眠
    */
    if (*p && *p != current) {
        (**p).state=0;
        goto repeat;
    }
    // 类似sleep_on的原理
    *p=NULL;
    if (tmp)
        tmp->state=0;
}
// 唤醒队列中的第一个节点,并清空链表,因为第一个节点会向后唤醒其他节点
void wake_up(struct task_struct **p)
{
    if (p && *p) {
        (**p).state=0;
        *p=NULL;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程杂技 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档