一.unix内核简单回顾(内存相关)
1. 当使用传统的分时调度策略的时候,在用户级执行的进程总会被分到时间片内执行,从而让所有的进程公平的共享CPU,在内核态执行的进程却不会分入时间片内执行,只有当前的内核进程明确允许的情况下,才能切换到内核级执行另一个进程。
2. 线程的开销比进程小主要体现在线程共享进程的地址空间。linux内核中没有线程的概念,使用的线程库,实现的功能是线程调度在内核进行,线程的管理在用户空间进行。从概念上看,每一个进程地址空间都分为用户地址空间和内核地址空间,linux中作进程切换的时候,如果是线程的切换,由于共用用户地址空间,所以用户空间的3G内存映射是不需要切换的,在内核中有对应的mm_struct对应,从而减少切换开销。
3. 地址空间的分配,一般是3G用户空间,1G内核空间 , 用户空间由text/data/bss/stack这几个部分组成,分别是程序指令,初始化数据,未初始化数据和堆栈。另外一些类型的段,如共享库和共享存储,都包含在用户地址空间内。共享库包括附加的正文,数据和BSS段,它们用于常用的函数和服务。共享存储在后面说明。
内核空间包括内核的正文和数据结构,当内核正在执行的时候,它可以访问整个地址空间,这样易于让内核在代表用户进程执行一次系统调用的时候可以在用户进程的地址空间中执行。一个内核进程实际上执行的都是内核的正文中的代码,有固定的映射,切换的时候重装task_struct等结构是必须的。
可以从下图中有个更加清晰的概念:(这里是2G/2G的设计)
4. 地址空间映射
线程切换减少开销主要是因为共享用户地址空间,所以用户空间地址映射的物理地址对应关系可以保存下来,不需要切换,从而减少开销。
内核负责将一个进程的虚拟地址空间映射到物理地址空间上,由MMU执行。
每一个进程都有它自己的映射关系,这种映射关系与内存有关,而且作为进程的现场的一部分保存起来。在进程运行的时候,内核将进程映射关系的描述提供给MMU。
注意,不是所有的虚拟页面都需要映射,例如,上图中的虚拟页面1,5,8就没有被映射到任何物理页面上,它们可以表示进程的地址空间中没有使用的页面,也可以是当前没有驻留在内存中的页面,如果一个进程试图返回后一种类型的页面,发生缺页错误之后,内核会将相应的物理页面调入到内存中,并且把虚拟页面映射到新分配的物理页面上。