Chinaunix首页 | 论坛 | 博客
  • 博客访问: 489529
  • 博文数量: 121
  • 博客积分: 4001
  • 博客等级: 上校
  • 技术积分: 1390
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-13 21:48
文章分类

全部博文(121)

文章存档

2011年(4)

2010年(11)

2009年(106)

我的朋友

分类:

2009-09-27 23:21:21

与其他大部分Unix变体和其他大部分的操作系统不同, Linux完整地支持内核抢占。
    在不支持内核抢占的内核中,内核代码可以一直执行,到它完成为止。也就是说,调度程序没有办法在一个内核级的任务正在执行的时候重新调度 -- 内核中的各任务是协作方式调度的,不具备抢占性。
    在2.6版的内核中,内核引人了抢占能力;现在,只要重新调度是安全的,那么内核就可以在任何时间抢占正在执行的任务。
    那么,什么时候重新调度才是安全的呢?只要没有持有锁,内核就可以进行抢占。锁是非抢占区域的标志。由于内核是支持SMP的,所以,如果没有持有锁,那么正在执行的代码就是可重新导入的,也就是可以抢占的。
    为了支持内核抢占所作的第一处变动就是每个进程的thread_info引入了preempt_count(thread_info.preempt_count)计数器。该计数器初始值为0,每当使用锁的时候数值加1,释放锁的时候数值减1。当数值为0的时候,内核就可执行抢占。从中断返回内核空间的时候,内核会检查need_resched和preempt_count的值。如果need_resched被设置,并且preempt_count为0的话,这说明有一个更为重要的任务需要执行并且可以安全地抢占,此时,调度程序就会调度(抢占当前进程)。如果preempt_count不为0,说明当前任务持有锁,所以抢占是不安全的。这时,就会像通常那样直接从中断返回当前执行进程。如果当前进程所持有的所有的锁都被释放了。那么preempt_count就会重新为0。此时,释放锁的代码会检查need_resched是否被设置。如果是的话,就会调用调度程序。有些内核代码需要允许或禁止内核抢占。
    如果内核中的进程被阻塞了,或它显式地调用了schedule(),内核抢占也会显式地发生。这种形式的内核代码从来都是受支持的,因为根本无需额外的逻辑来保证内核可以安全地发生被抢占。如果代码显式的调用了schedule(),那么它应该清楚自己是可以安全地被抢占的。
    内核抢占发生在:
    (1) 当"从中断处理程序"正在执行,且返回内核空间之前
    (2) 内核代码再一次具有可抢占性的时候
    (3) 如果内核中的任务显式的调用schedule()
    (4) 如果内核中的任务阻塞(这同样也会导致调用schedule())

注:
---------------------------------------------------
    current->thread_info.flags中TIF_NEED_RESCHED为1,表示当前进程需要执行schedule()释放CPU控制权
    current->thread_info.preempt_count的值不为0,表示当前进程持有锁不能释放CPU控制权(不能被抢占)
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hanwei_1049/archive/2009/03/14/3991092.aspx
阅读(1365) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~