linux总结

精简的linux系统概念模型

linux内核实现了操作系统关键的三个重要模块,分别是进程管理、内存管理、文件系统。

进程管理

        进程的描述:linux内核中用一个数据结构struct task_struct来描述进程,该数据结构非常的庞杂,存储了进程的各种信息,如进程的状态、堆栈、有关父进程和子进程的信息以及控制台、文件系统等各种信息。

        其中,init_task为第一个进程(0号进程),它的初始化是通过硬编码方式固定下来的。之后的所有其他进程的初始化都是通过do_fork复制父进程的方式初始化的。 1号和2号进程的创建是由rest_init通过kernel_thread创建了的:一个是kernel_init,最终把用户态的进程init给启动起来,是所有用户进程的祖先;另一个是kthreadd内核线程,kthreadd内核线程是所有内核线程的祖先,负责管理所有内核线程。除了pid=1的init进程外,所有进程都有父进程,父子进程以树型结构的方式存在,父进程创建出来的多个子进程之间称为兄弟进程。

        不管是kernel_thread和fork有关的系统调用,想要创建一个进程最终都是通过_do_fork创建。_do_fork函数主要完成了调用copy_process()复制父进程、获得pid、调用 wake_up_new_task将子进程加入就绪队列等待调度执行。copy_process()中又有dup_task_struct和copy_thread_tls两个函数,dup_task_struct实际完成进程描述符的拷贝,copy_thread_tls负责构造fork系统调用在子进程的内核堆栈。子进程创建好了进程描述符、内核堆栈等,就可以通过 wake_up_new_task(p)将子进程添加到就绪队列,之后子进程将从ret_from_fork开始执行。

        进程进入就绪队列后就是TASK_RUNNING状态(在linux中就绪和执行状态都是TASK_RUNNING),之后由调度策略选择就绪的进程进入CPU执行。实时进程需要很短的响应时间,所以采用FIFO(先进先出)或者Round Robin(时间片轮转)的调度策略。普通进程(SCHED_NORMAL)使用的是Linux 2.6.23版本内核中引入的CFS(Complete Fair Scheduler)调度管理程序,分到的CPU时间和进程优先级(nice值)有关。无论使用什么调度算法,Linux系统的用户都无法直接让调度器去优先调度哪个进程,因为调度对用户来说是未知的。但是,用户可以通过修改优先级间接地影响Linux的调度器。

        进程的时间片用完或者其它需要操作系统的情况,进程需要陷入操作系统,让操作系统占有CPU,从而需要进程切换。需要保存进程的上下文环境,使其重新获得CPU时可以恢复现场。

        当进程执行完成后,进程会退出,但是进程在进程表上删去之前需要让父进程可以去获取该子进程的退出状态码,之后才会在进程表上清理掉这个表项。进程在结束执行、父进程获得该子进程的退出状态码之间的状态称为僵尸态。

内存管理

        每个进程都有自己的虚拟地址空间,虚拟地址空间的范围和物理内存大小一样,所以每一个进程都认为自己独占了内存。操作系统为虚拟地址空间已使用的空间,在实际内存中分配物理地址。

        每个进程的虚拟地址空间中都有内核空间,且在每个进程中所占的虚拟地址相同,它们映射到相同的物理地址空间,用于操作系统内核。另外还有用户空间,这是每个进程独有的且相互独立,分别映射到物理上的不同地址。用户看到的一般是虚拟空间,所以需要使用页表进行虚拟地址和物理地址的转换。       

        用户空间又进行了段落的划分,分为代码段、数据段、堆、栈等。代码段存放程序执行代码;数据段通常是指用来存放程序中已初始化的全局变量的一块内存区域,属于静态内存分配。堆是用于存放进程运行中被动态分配的内存段,栈是用户存放程序临时创建的局部变量。每个段都会使用基址寄存器和界限寄存器来放段的起点和长度,虚拟地址和物理地址的转换时会检查访问的地址的偏移是否大于界限寄存器的值,大于则产生段错误。

         为了加速使用页表进行虚拟地址和物理地址的转换,可以把一些页的翻译信息存放在缓存中,这就是快表(TLB)。其实就是把页表的表项放在L1级缓存和L2级缓存,因为缓存速度比内存更快而加速。缓存中存放的翻译信息有限,如何替换则有响应的替换算法。因为不同的进程的虚拟地址可能相同,为了保证快表的虚拟地址之间不混淆,还会给每一个翻译信息加上进程标识。

         物理内存如果耗尽时如果还请求分配,就会报错out-of-memory(OOM)表示内存不足,这时Linux操作系统会选择占用过多内存的进程终止。

文件系统

         文件控制块是系统为每个文件设置一个描述性数据结构,它记录了系统管理文件的全部信息,在Linux中文件控制块称为inode,文件目录就是文件控制块的有序集合。

         文件存储设备分成若干个物理块,以块为单位在内存和存储设备之间交换信息,文件存储空间的管理实质上是一个空闲块的组织和管理。

         文件从存储设备读取到缓冲空间需要open、read等系统调用,所以需要操作系统的帮助。文件读取后会返回给用户空间一个文件描述符,用来操作数据,不过操作的功能很有限,但是现代编程语言有比文件描述符更高一级的对象,由此提供了更多的功能和便利。

         但是文件系统的种类很多,为了实现对不同文件系统的支持,在用户和具体的文件系统之间提供了一个统一和抽象的虚拟文件系统(VFS),对用户隐去了各种文件系统的具体实现。

影响应用程序性能表现的因素

1、进程调度的策略

FIFO的调度有更短的周转时间,所以用于实时进程,而不是单纯的使用时间片轮转。

2、缓存的命中率和缺页IO的次数

因为局部性原理,所以存取数据时多取一点物理地址相近的数据可以改善时间,操作系统在读取数据时就会读取更多一点的数据。一个良好的替换算法和OOM的处理策略也是同理。

 

SA20225282

posted @ 2021-05-18 22:57  282  阅读(102)  评论(0编辑  收藏  举报