免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1044 | 回复: 1
打印 上一主题 下一主题

我也说说对kernel v0.11中sleep_on()函数的理解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-03-27 12:08 |只看该作者 |倒序浏览
看着赵炯博士的《Linux内核完全注释》写的,虽然赵博士解释的已经很详细了,可是我辈理解起来还是有些困难废话少说,直入正题。
linux/kernel/sched.c中sleep_on()函数体如下:为解释起见已经按行编号。

1 void sleep_on(struct task_struct **p)
2 {
3  struct task_struct *tmp;
4  if (!p)
5   return;
6  if (current == &(init_task.task))
7   panic("task[0] trying to sleep";
8  tmp = *p;
9  *p = current;
10  current->state = TASK_UNINTERRUPTIBLE;
11  schedule();
12  if (tmp)
13  tmp->state=0;
14 }

    第4行的意思是如果传入的指针为空(*p指向任务结构,可以为空,但p是一指针变量不能是0)则退出。
    第6行是说如果试图把任务0放入睡眠队列则死机(决不允许,呵呵)。否则(第8-10行)保存等待任务队列头指针*p到tmp,并使该指针*p指向当前任务(亦即把当前任务置入等待队列中)。通过这三行操作,即建立起一个隐式等待队列(赵博士所言)。我理解这里也是花了很长时间才搞定,而且到现在还有不明白的地方。不管怎样,考虑向一个空的等待任务队列添加一个或两个等待任务的时候指针的变化,这会帮助你理解的。如下图所示。

初始状态时(1),等待队列为空,*p指向NULL,图中用一个假想的NULL对象表示。当有一个等待任务加入时,按照代码8、9两行,tmp指向*p,而当时*p指向NULL,从而T1.tmp指向NULL,然后令*p指向current,这里就是T1,所以最终各个指针的指向就如途中(2)所示。依此类推,当第二个等待任务T2加入后,指针状态如图中(3)所示。
    第11行调用schedule()函数调度其他进程运行,而当前进程则进入不可中断的等待状态,直到有wake_up()函数(也在sched.c中)将该任务明确唤醒。我们应该了解,sleep_on()函数总是被某一个进程所调用的,schedule()函数调用switch_to()时保存了当前进程所有寄存器状态,那么当前进程被唤醒后由schedule()函数调度执行时就恢复到11行调用schedule()时的状态,唯一的区别是任务状态变成了RUNNING。这时它会从下一条语句处继续执行(12行开始)。
    第12行去检查tmp指针的状态——如上面图中所示,它保存了等待任务队列中下一个等待任务的指针。如果还有等待任务的话,那么也将其唤醒。按赵博士的说法,这会唤醒所有等待同一资源的进程——当队列头所指向的任务唤醒后,schedule()也会对它进行同当前任务同样的操作,就好像一条链子一样。

论坛徽章:
0
2 [报告]
发表于 2006-04-17 11:24 |只看该作者
楼主分析德很好~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP