加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

kernel学习之进程抢占和切换

发布时间:2016-09-10 19:21:56 所属栏目:Unix 来源:站长网
导读:抢占时伴随着schedule()的执行。内核提供了一个TIF_NEED_RESCHED标志来表明是否要用schedule()调度一次。 根据抢占发生的时机分为用户抢占和内核抢占。用户抢占

抢占时伴随着schedule()的执行。内核提供了一个TIF_NEED_RESCHED标志来表明是否要用schedule()调度一次。

根据抢占发生的时机分为用户抢占和内核抢占。用户抢占发生在内核即将返回到用户空间的时候。内核抢占发生在返回内核空间的时候。

1、用户抢占:内核在即将返回用户空间时检查进程是否设置了TIF_NEED_RESCHED标志,如果设置了,就会发生用户抢占。用户抢占发生的时机:从系统调用或中断处理程序返回用户空间的时候。

2、内核抢占:在不支持内核抢占的内核中,内核进程如果自己不主动停止,就会一直的运行下去。无法响应实时进程。抢占内核虽然牺牲了上下文切换的开销,但获得了更大的吞吐量和响应时间。2.6的内核添加了内核抢占,同时为了某些地方不被抢占,又添加了自旋锁。在进程的thread_info结构中添加了preempt_count该数值为0,当进程使用一个自旋锁时就加1,释放一个自旋锁时就减1.为0时表示内核可以抢占。

内核发生抢占的时机:1、从中断处理程序返回内核空间时,内核会检查preempt_count和TIF_NEED_RESCHED标志,如果进程设置了TIF_NEED_RESCHED标志,并且preempt_count为0,发生内核抢占。2、当内核再次用于可抢占性的时候,当进程所有的自旋锁都释放了,释放程序会检查TIF_NEED_RESCHED标志,如果设置了就会调用schedule。3、显示调用schedule时4、内核中的进程被堵塞的时候。

进程的切换:

从一个运行的进程转换到另一个可运行的进程时,称为进程切换(process switch)或上下文切换(context switch).

1、硬件上下文(hardware context)

2、任务状态段tss

3、硬件上下文的切换:linux内核中的硬件上下文不像intel原始设计的那样存放在tss中而是用一个特定了数据结构来存储。

4、context_switch

/* 
     
 *context_switch - switch to the new MM and the new 
 *thread's register state. 
 */
      
static inline void
context_switch(struct rq *rq, structtask_struct *prev,  
            struct task_struct *next)  
{  
     structmm_struct *mm, *oldmm;  
     prepare_task_switch(rq,prev, next);  
     trace_sched_switch(prev,next);  
     /*获取即将调度的进程内存指针*/
     mm =next->mm;  
     /*保存当前要替换的进程使用的内存数据结构*/
     oldmm= prev->active_mm;  
     /* 
      * For paravirt, this is coupled with an exitin switch_to to 
*查看本栏目更多精彩内容:http://www.bianceng.cn/OS/unix/
      * combine the page table reload and the switchbackend into 
      * one hypercall. 
      */
     arch_start_context_switch(prev);  
     /*如果指向的即将调用的进程内存指针为null,则为内核线程*/
     if(!mm) {  
         next->active_mm= oldmm;  
         /*内存描述结构使用计数加1*/
         atomic_inc(&oldmm->mm_count);  
         enter_lazy_tlb(oldmm,next);  
     }else
      
         /*不是内核线程,切换页表*/
         switch_mm(oldmm,mm, next);  
      
     if(!prev->mm) {  
         prev->active_mm= NULL;  
         rq->prev_mm= oldmm;  
     }  
      
     /* 
     
      * Since the runqueue lock will be released bythe next 
      * task (which is an invalid locking op but inthe case 
      * of the scheduler it's an obviousspecial-case), so we 
      * do an early lockdep release here: 
      */
      
#ifndef __ARCH_WANT_UNLOCKED_CTXSW  
     spin_release(&rq->lock.dep_map,1, _THIS_IP_);  
#endif  
      
     /*Here we just switch the register state and the stack. */
     /*处理器状态切换*/
     switch_to(prev,next, prev);  
     barrier();  
      
     /* 
      * this_rq must be evaluated again because prevmay have moved 
      * CPUs since it called schedule(), thus the'rq' on its stack 
      * frame will be invalid. 
      */
     finish_task_switch(this_rq(),prev);  
      
}

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读