黄志恒
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
这篇文章讨论一下Linux内核进程调度和进程切换。
首先说明一下,这里不涉及进程调度算法。想看调度算法的亲请参阅各种操作系统书籍 - -!
我们这里讲一讲内核在做进程调度和进程切换的时候做了些什么。
进程调度时机:
1、中断处理过程(包括时钟中断,I/O中断,系统调用和异常)中,直接调用schedule()或者返回用户态时根据need_resched标记调用schedule()。
2、内核线程可以直接调用schedule()进行进程切换,也可以在中断处理过程中进行调度,也就是说内核线程作为一类特殊的进程可以主动调度,也可以被动调度。
3、用户态进程无法实现主动调度,仅能通过陷入内核态后的某个时机点进行调度,即在中断处理过程中进行调度。
注意:进程调度的方法是schedule()无论怎么封装,进程调度最后都会进入这个schedule()函数中执行。
schedule()函数:
这个函数中有以下几个关键点:
1、next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部。你看,无论使用哪种进程调度算法,最后都给返回成一个next,所以我们这里不具体分析进程调度算法
2、context_switch(rq, prev, next);//进程上下文切换 prev是当前,next是要切换的。
3、switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程。这个swich_to一执行就进行了进程切换。
这里讲的很笼统,linux内核在调度的时候会一如既往的考虑很多内容,对很多条件进行判断。我给出schedule(0源代码地址,有兴趣可以仔细琢磨一下http://codelab.shiyanlou.com/xref/linux-3.18.6/kernel/sched/core.c#__schedule。
Linux进程调度的一般执行过程下面这张图总结的很好了,我就贴上来不再手敲了:
感谢孟老师~
总结:
在最后一周,孟老师提出了“舞女”这么个内核概念。听了之后感觉很形象,也让我对内核有了一个更宏观的认识。下面我给大家来学一学。
在linux中,0-3G内存是用户态可以访问的,3G-4G的地址空间是专供内核态访问的。但是呢,这个3G-4G是各个进程共享的。因为各进程进入的内核态是同一块地址,当从内核态出来后才会进入不同的用户态。内核态就当于一辆出租车,没客人的时候在idea进程中空转,有客人了就带着客人跑一段。当然了,内核态也可以说成是taxi girl。具体的细节……那啥,你懂得~
总的来说,内核就是各种中断处理过程和内核线程的集合。我们这里省去了linux操作系统很多其他东西,专注于内核。
这里放出一张图,大家可以很清晰的看到linux操作系统的构造
当然了,从不同角度看操作系统也会有不同的内容。下面是从常用的内存和CPU的两个角度来看linux操作系统的执行:
这是内存角度。
这是CPU角度。
最后以一张linux最见到也最复杂的操作的图示来结束本篇文章:
再次感谢孟宁老师的授课!