>sleep_on注释错误

linux内核完全剖析 P283页,

内核函数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");
    tmp = *p;
    *p = current;
    current->state = TASK_UNINTERRUPTIBLE;
    schedule();
    if(tmp)  //在源代码文件linux/kernel/sched.c中为163行
       tmp->state = 0;
}

注释中说在163行之前要加入*p=tmp,其实是错的。首先,当有wake_up()程序唤醒此不可中断睡眠后,是唤醒了整个以*p为队伍头的等待任务队列,所以此时会设置*p = NULL,即睡眠队列不再存在。如果程序运行到了163行,表示此进程已经被唤醒,则说明已经有进程调用了wake_up()函数,此时需要让整个队列上的进程都唤醒,即处于运行状态,即置state为0,而在上面的函数中,tmp实际上就是指向现在队列中还处于睡眠状态的队列头,置其状态为运行状态,当CPU在下一个时间片运行时,就有可能可以被唤醒了,依次下去可以唤醒整个队列。而为什么不能加*p=tmp呢,真正的原因是,当唤醒了一个进程后,如果加上代码*p=tmp,假如此时又有一个进程调用上面的函数要睡眠在这个队列之上,这个任务在sleep_on中的tmp应该指向哪里?显然此时队列中应该只有这个任务,tmp应指向NULL,此时*p应为NULL,所以等待队列要完全重新建立。
注:p为一个全局变量,相当于所有的进程在内核态都可以访问,而tmp为一个局部变量,在每个进程的内核态堆栈中都会有一个值,这个值指向上一个等待的任务,所以队列实际上是由tmp来维护的。
ps1:该死的本书的作者赵炯,竟然分析错了。本来我只是怀疑,在网上一查,果真是书上写错了。
ps2:欣赏linus,这么复杂的算法都想得这么周到,牛
ps3:但对于interrupble_sleep_on函数,linux源代码的确是存在一个问题,(打住吧)。

估计也没什么人能理解这该死的内核代码,RTFSC(read the fucking source code)吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值