linux内核子系统

来源:互联网 发布:淘宝优惠券哪里领 编辑:程序博客网 时间:2024/06/05 08:28

1.linux内存管理子系统

1.1内存管理模型

1.2地址映射管理

1.2.1虚拟地址空间的分布

对于32位的系统,寻址范围为4G,0-3G为用户空间,即运行应用程序。3-4G为内核空间,内核空间又被划分为4个部分,这4个部分分别为:

1.直接映射区,内存范围为3G到3G+896M,包括数据区和代码区,映射关系简单

2.vmalloc区

3.永久内核映射

4.固定映射的线性地址

问题:为什么他们被划分为4个部分?

    因为这4个部分映射到物理地址的方式是不同地

1.2.2虚拟地址转化为物理地址

32位地址的高十位作为偏移,cr3作为基地址,相加后就能从页目录中得到一个地址,这个地址作为页表的基地址,加上中间10位的偏移量,就能得到一个物理页的基地址,再加上低十位的偏移,最终得到物理页的存储单元,一个物理页(页帧)通常为4KB

1.3物理地址分配管理

什么时候分配物理内存?

只有当访问虚拟内存的时候才会真正分配物理内存。kmalloc比较特殊,它分配到的虚拟地址已经有物理内存对应

2.linux进程管理子系统

2.1.linux进程要素

2.1.1程序与进程

程序是存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体

进程是一个执行中的程序,他是动态的实体

2.1.2进程四要素

1.有一段程序供其执行,这段程序不一定是某个进程所独有,可以与其他进程共用。

2.有进程专用的内核空间堆栈。

3.在内核中有一个task_struct的数据结构,即通常所说的进程控制块,有了它进程才能成为内核调度的一个基本单位。

4.有独立的用户空间,用户线程只有共享的用户空间,内核线程没有用户空间。

2.1.3linux进程状态

1.TASK_RUNNING

    进程正在被cpu执行,或者已经准备就绪,随时可以执行。当一个进程刚被创建时,就处于此状态。

2.TASK_INTERRUPTIBLE

    处于等待中的进程,待等待条件为真时被唤醒,也可以被信号或者中断唤醒

3.TASK_UNINTERRUPTIBLE

    处于等待中的进程,待资源有效时唤醒,单不可以由其他进程通过信号或中断唤醒

4.TASK_KILLABLE

    linux2.5.25新引入的进程睡眠状态,原理类似于TASK_UNINTERRUPTIBLE,但是可以被致命信号(SIGKILL)唤醒。

5.TASK_TRACED

    正处于调试状态的进程。

6.TASK_DEAD

    进程退出时(调用do_exit),所处的状态。

2.1.4linux进程描述

在linux内核代码中,线程和进程都使用了结构task_struct来表示(充当PCB进程控制块),在sched.h里,它包含了大量描述进程和线程的信息,其中比较重要的有:

pid_t pid;    //进程号

long state;    //进程状态

Int prio;    //进程优先级

2.2.linux进程调度

调度就是从就绪的进程中选出最适合的一个来执行

2.2.1 调度策略

主要分为两个部分,对于实时进程和普通进程

SCHED_NORMAL(SCHED_OTHER):普通的分时进程

SCHED_FIFO:先入先出的实时进程

SCHED_RR:时间片轮转的实时进程

SCHED_BATCH:批处理进程

SCHED_IDLE:只在系统空闲时才能被调度执行的进程

2.2.2 调度实机

即achedule()函数什么时候被调用?

主动式:在内核中直接调用achedule()。当进程需要等待资源而暂时停止运行时,会把自己的状态挂起(睡眠),并主动请求调度,让出cpu

范例:current->state = TASK_INTERRUPTABLE;    /*current为task_struct类型指针,state为进程状态,阻塞*/schedule();

被动式:即抢占式调度,又分为用户态抢占和内核态抢占

1.用户态抢占发生在:

    * 从系统调用返回用户空间

    * 从终端处理程序返回用户空间

    内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,即发生用户抢占。

    * 当某个进程耗尽它的时间片时,会设置need_resched标志

    * 当一个优先级更高的进程进入可执行状态时,也会设置need_resched标志。

2.内核态抢占

    用户态抢占的缺陷

        进程/线程一旦运行到内核态,就可以一直执行,直到它主动放弃或者时间片耗尽为止,这样会导致一些非常紧急的进程或线程长时间得不到运行,降低整个系统的实时性。

    改进方式:允许系统在内核态也支持抢占,更高优先级的进程/线程可以抢占在内核态运行的低优先级进程/线程。

内核抢占可能发生在:

    * 中断处理程序完成,返回内核空间之前。

    * 当内核代码再一次具有可抢占的时候,如解锁或使能软中断等。

注意:某些特例下是不允许抢占的:

    * 内核正在运行中断处理

    * 内核正在进行中断上下文的Bottom Half(中断的底半部)处理。硬件中断返回前会执行软中断,此时任然处于中断上下文中。

    * 进程正持有spinlock自旋锁,writelock/readlock读写锁等

    * 内核正在执行调度程序Schedule。

抢占计数

    为了保证linux内核在以上情况不会被抢占,抢占式内核使用了一个变量preempt_count,称为内核抢占计数。这个变量被设置在进程的thread_info结构中,每当内核要进入以上几种状态时,该变量加1,指示内核不允许抢占。每当内核从以上几种状态退出时,该变量减1,同时进行可抢占的判断与调度。

2.2.3 调度步骤

schedule函数工作流程如下:

    1. 清理当前运行中的进程

    2.  选择下一个要运行的进程

    3. 设置新进程的运行环境

    4. 进行上下文的切换

0 0
原创粉丝点击