免费注册 查看新帖 |

Chinaunix

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

关于内核调度的一点疑问 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-01-10 15:50 |只看该作者 |倒序浏览
类似下面的函数:
signed long __sched schedule_timeout_interruptible(signed long timeout)
{
        __set_current_state(TASK_INTERRUPTIBLE);
        return schedule_timeout(timeout);
}

如果__set_current_state(TASK_INTERRUPTIBLE)执行完毕,定时器开启之前,发生中断有可能高优先级的其他进程抢占当前进程。那么当前进程是挂在等待队列吗?当前状态不是TASK_RUNNING,调度程序如何使其再次运行的?

论坛徽章:
0
2 [报告]
发表于 2011-01-10 17:42 |只看该作者
按楼主理解那可运行的程序对于单cpu情况下,岂不是只有一个了?
可运行的程序由多个可运行进程链表管理的。

论坛徽章:
0
3 [报告]
发表于 2011-01-10 18:55 |只看该作者
回复 2# EZWORD


自认为技术人员的我表达看来真有问题。不好意思,可能我没表达清楚我的困惑之处。

就以上面的schedule_timeout_interruptible函数为例。
如果内核代码(包括驱动代码)调用此函数,在__set_current_state(TASK_INTERRUPTIBLE)之前被抢占,调度程序将当前进程放入可执行队列(状态还是TASK_RUNNING,没疑问),执行调度程序。因为是放在可执行队列,再次调度没什么疑问。
如果程序没有被抢占,在__set_current_state(TASK_INTERRUPTIBLE)之后启动完定时器,然后执行调度程序。调度程序把当前进程放入等待队列(什么等待队列我不关心),调度程序暂时是不会调度此进程继续运行的。当定时器时间到了之后会把当前进程状态设置为TASK_RUNNING,然后放入可执行队列。没有疑问。

我的困惑是:如果抢占发生在__set_current_state(TASK_INTERRUPTIBLE)之后,当然定时器还没设置完,调度程序如何处理的……
当然所有的这一切都要求允许抢占,是否可以抢占我也不确定。但我觉得设置完__set_current_state(TASK_INTERRUPTIBLE),产生中断,要求调度以及没有占有锁两个条件同时满足应该是大有可能的。

论坛徽章:
0
4 [报告]
发表于 2011-01-10 19:26 |只看该作者
我的理解是:进程能不能被调度,并不在于它的状态是不是TASK_RUNNING,而在于它在不在运行队列里面。
__set_current_state(TASK_INTERRUPTIBLE)之后,进程依然在运行队列里面,所以它还有机会被调度。
进程要到什么时候才会被移出运行队列呢?是在schedule函数里面,如果发现进程状态不是TASK_RUNNING,则移出运行队列。而在schedule里面,抢占是被禁止的,并且还要对运行队列上锁。

论坛徽章:
0
5 [报告]
发表于 2011-01-10 19:45 |只看该作者
回复 4# kouu


谢谢指教!

如果抢占发生在__set_current_state(TASK_INTERRUPTIBLE)之后,当然定时器还没设置完,说白了,就是调度程序运行了,锁住什么不关心,调度程序执行的时候肯定不能也不需要再执行调度程序。此时发现当前进程状态不是TASK_RUNNING,把它移出队列(当然,在此是不是要详加判断其他条件我不清楚),可是定时器还没开启,那岂不是不能设置回TASK_RUNNING,这应该不是真实的结果吧。

论坛徽章:
0
6 [报告]
发表于 2011-01-10 20:10 |只看该作者
本帖最后由 EZWORD 于 2011-01-10 20:11 编辑

神马啊,设置完了状态,又没有移出运行队列,除非掉用那个schedule_timeout,其代码如下:

  1.         signed long schedule_timeout(signed long timeout)
  2. {
  3. timer_t timer;
  4. unsigned long expire;

  5. switch (timeout)
  6. {
  7. case MAX_SCHEDULE_TIMEOUT:
  8. schedule();//此处必须自己去唤醒这个任务。
  9. goto out;
  10. default:
  11. if (timeout < 0)
  12. {
  13. printk(KERN_ERR “schedule_timeout: wrong timeout “
  14. “value %lx from %p\n”, timeout,
  15. __builtin_return_address(0));
  16. current->state = TASK_RUNNING;
  17. goto out;
  18. }
  19. }
  20. expire = timeout + jiffies;
  21. init_timer(&timer);
  22. timer.expires = expire;
  23. timer.data = (unsigned long) current;
  24. timer.function = process_timeout;
  25. add_timer(&timer);
  26. schedule();//再次调度时返回位置
  27. del_timer_sync(&timer);
  28. timeout = expire - jiffies;
  29. out:
  30. return timeout < 0 ? 0 : timeout;
  31. }

复制代码

论坛徽章:
0
7 [报告]
发表于 2011-01-10 20:24 |只看该作者
回复 6# EZWORD


不是呀,哥们,我的困惑不在于正常执行完毕,在于如果有抢占!设置完了状态,定时器还没有设置完成,在此发生抢占,抢占实际上就是调用schedule()找到优先级最高的进程进行切换(这个我理解不知道有没有问题?),当前进程状态不是TASK_RUNNING,切换的进程比当前进程优先级高,这样的情况是调度程序如何处理的?原进程是放在运行队列还是等待队列?因为我觉得放哪都有问题,困惑在于此!

论坛徽章:
0
8 [报告]
发表于 2011-01-10 20:36 |只看该作者
你的这个定时器不是指上面代码的22-25行?

论坛徽章:
0
9 [报告]
发表于 2011-01-10 20:43 |只看该作者
本帖最后由 azfa123 于 2011-01-10 20:47 编辑

回复 8# EZWORD

是呀,这个很关键吗?设置完状态和定时器操作完成并非原子的,如果抢占发生在21,22,23,24,25甚至26里面,如何处理的……

论坛徽章:
0
10 [报告]
发表于 2011-01-10 21:14 |只看该作者
不关键,关键在的在于它还在运行队列中。。。。
个人理解,呵呵,其实我也不是很懂
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP