Chinaunix首页 | 论坛 | 博客
  • 博客访问: 488708
  • 博文数量: 76
  • 博客积分: 5196
  • 博客等级: 大校
  • 技术积分: 1414
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-10 18:43
个人简介

转了个圈,又回来了

文章分类

全部博文(76)

文章存档

2013年(1)

2011年(8)

2010年(9)

2009年(22)

2008年(36)

我的朋友

分类: LINUX

2010-06-03 14:13:23

书籍:Linux 内核设计与实现(第二版) P44 4.3抢占和上下文切换
 
上下文切换:就是从一个进程上下文切换到另外一个进程上下文。

这里所说的进程上下文涉及两个方面:虚拟内存,寄存器和栈。上下文切换所做的工作就是与这两个方面相关。首先会把虚拟内存的映射从上一个进程映射到新的进程,然后会保存上一个进程的处理器信息,也就是寄存器和栈信息,同时会恢复新进进程的处理器信息。
那么什么时候会发送进程切换呢?即内核什么时候调用schedule()函数呢?
当然,用户进程可以显示的调用这个函数,同时在引起进程阻塞的函数也会调用该函数。如果仅仅是这样,一个进程就可能永远执行下去,不会让出CPU。
 
内核提供了下面一种机制来判断是否需要进行进程调度:
内核为每一个进程都设置了一个need_resched标志,表明是否需要进程进程调度。在下面的一些情况下可能该标志会被改变,
(1) 当某个进程的时间片被用完的时候,在系统时钟中断函数会调用scheduler_tick()函数来设置这个标志。
(2) 当有优先级别更高的进程进入可执行状态的时候,try_to_wake_up()会设置这个标志。
也就是说只要时间片用完或者有更高级别的进程进入可执行状态,就会发生进程切换。
下面再来看看用户抢占和内核抢占的概念:
首先记住抢占就是有别的进程来抢占处理器,也就是什么情况引发了拥有处理器的进程让出处理器。
用户抢占:是指当内核即将返回用户空间的时候,如果该该进程的need_resched标志被置位,就会调用schedule(),发生进程切换 也就是用户态的进程切换。
怎么样理解这句话呢,关键理解内核返回用户空间这几话。一个进程如何进入内核空间,只有调用系统调用。一个进程运行在用户空间,当天调用系统调用的时候,就会陷入内核空间,但是此时被调用的内核代码任然处于调用它的进程的上下文中。当处理器执行完内核代码后,就会返回到用户空间。
同时,处理器从一个进程用户空间进入内核空间的另外一种方式就是被中断。
内核在从内核空间返回到用户空间的时候都会检查need_resched标志是否被置位。总结起来就是下面两种情况:
(1) 从系统调用返回用户空间,比如说可能执行了wake_up函数唤醒了更高优先级别的进程,或者进程在用户空间被阻塞。
(2) 从中断处理程序返回,比如从系统时钟中断处理程序,或者说在某个中断处理程序中唤醒了更高优先级别的进程。
 
再来看内核抢占:
首先我们来理解什么是可抢占式内核。Linux完整的支持了内核抢占,preempt。在不支持内核抢占的操作系统中,内核代码会一直执行到结束,不会被打断,调度程序不会在一个内核级的任务在执行的时候进行调度。现在,Linux是支持内核抢占的,也就是说只要有更高级别的进程进入了可执行状态,不管当前进程是运行在用户态还是内核态,都要被抢占。
在内核态下,进程能不抢占的条件之一就是内核抢占没有被禁止。所以在这里除了need_resched标志外,还增添了一个表明内核是否被禁止抢占的标志preempt_count。preempt_count跟自旋锁联系在一起,当内核获得一个锁的时候,会禁止内核调用,preempt_count会自加。释放锁的时候,preempt_count会自减,当preempt_count为0时,表明内核是可以被抢占的。内核抢占可能发生在一下几种情况:
(1)内核中的任务显示的调用schedule()。
(2)内核任务被阻塞。
(3)中断处理程序返回内核空间之前。
(4)当内核再一次具有可占性的时候,也就是当内核人释放到所有所持锁的时候。
阅读(1458) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~