Linux操作系统分析_课程学习总结

2021/5/11 7:27:27

本文主要是介绍Linux操作系统分析_课程学习总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、精简的Linux系统概念模型

Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。

其主要结构如下:

 

Linux系统的核心是内核。内核控制着计算机系统上的所有硬件和软件,在必要时分配硬件,并根据需要执行软件。内核主要负责进程管理、内存管理、文件系统、驱动管理等。

二、进程管理

1  进程的描述

进程管理是linux系统的核心部分,在Linux内核中⽤⼀个数据结构struct task_struct来描述进程,直接或间接提供了进程相关的所有信息。struct task_struct的结构包括了进程的状态、进程双向链表的管理,以及控制台tty、⽂件系统fs的描述、进程打开⽂件的⽂件描述符files、内存管理的描述mm,还有进程间通信的信号signal的描述等内容。

2  进程的创建

 init_task为第⼀个进程(0号进程)的进程描述符结构体变量,它的初始化是通过硬编码⽅式固定下来的。除此之外,所有其他进程的初始化都是通过do_fork复制⽗进程的⽅式初始化的。1号和2号进程的创建是start_kernel初始化到最后由rest_ init通kernel_thread创建了两个内核线程:⼀个是kernel_init,最终把⽤户态的进程init给启动起来,是所有⽤户进程的祖先;另⼀个是kthreadd内核线程,kthreadd内核线程是所有内核线程的祖先,负责管理所有内核线程。父进程创建子进程过程如图:

  

 

 

 

 

 

 

 

3  进程的状态

操作系统原理中的进程有就绪态、运⾏态、阻塞态这3种基本状态,而实际的Linux内核管理的进程状态有些不同,就绪态和运行态,在linux中都是TASK_RUNNING态。各种状态和转换见下图:

 

 

4、进程调度

包括先到先服务算法、最短作业优先调度、优先级调度、 轮转法调度、多级队列调度、多级队列反馈调度等。进程调度一般发生在中断返回前,其中进程上下文的切换是进程调度的必要步骤。一个进程的上下文包括进程的控制信息以及有关程序、数据等。进程切换主要有以下两步组成:切换页全局目录以安装一个新的地址空间;切换内核态堆栈和硬件上下文。硬件上下文提供了内核执行新进程所需要的所有信息,包括CPU寄存器。尽管每个进程可以有自己的地址空间,但所有的进程只能共享CPU的寄存器。 因此,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。这样才能正确的恢复一个进程的执行硬件上下文:进程恢复执行前必须装入寄存器的一组数据,包括通用寄存器的值以及一些系统寄存器。我们通过switch_to宏执行进程切换,schedule()函数调用这个宏来调度一个新的进程在CPU上运行。

三、中断管理

中断是计算机的三大法宝之一,分外部中断(硬件中断)和内部中断(软件中断),其中软件系统调用作为一种特殊的中断,就是利用陷阱(trap)这种软件中断式主动从用户态进入内核态的。

其中系统调用机制如下图:

中断执行过程:

确定中断向量,利用idtr找到中断入口地址,确定特权级是否匹配,是否需要变更堆栈段,然后在栈中保存eflags、cs和eip的内容(保存在被中断进程的内核栈中)如果异常产生一个硬件出错码,则将它保存在栈中,然后装载cs和eip寄存器,执行中断处理程序。

中断返回:

用保存在栈中的值装载cs、eip和eflags寄存器。如果一个硬件出错码曾被压入栈中,那么弹出这个硬件出错码,检查中断前是否在内核态,如果不是,从栈中装载ss和esp,回退到用户态。

四.文件系统

进程是程序的一次活动。 Linux设备驱动和代码文件、可执行文件都存储在文件系统中。Linux系统使用vfs向上提供服务,向下兼容不同的具体文件系统。

进程打开文件时。会维护一个进程的文件打开表fd,fd指向一个系统的文件打开表。在系统文件打开表中,存在一个f_op,对应的是具体的文件系统操作函数(read/write)。

五.具体实例

这里描述读写文件的过程。在读写文件之前,必须使用oepn打开一个文件,打开文件首先open会执行到C库,C库里有INT $0x80指令,然后在中断向量表中找到128项,中断向量表里有中断描述符,可以找到中断处理程序入口,第128项是系统调用处理函数,进入系统调用处理函数,保存现场,系统调用号存储eax中,根据系统调用号执行系统调用表中对那一项的函数。系统调用表是相应的函数指针,这里会执行sys_open。sys_open进行命令查找,找到文件控制块,根据不同文件类型,调用文件打开函数,文件打开函数会创建一个系统文件打开表file,file的很多内容来自文件控制块,填完之后,进程也有一个进程文件打开表,这个结构里面有fd数组,fd数组是指针,找个空闲的,把它指向之前已经创建的file结构,最后返回那一项的索引号,即fd。

当进程使用read系统调用读这个文件,就会根据fd数组的下标 找到fd数组的对应项,然后找到指向之前创建的file结构的指针,再找到这个file结构,最后找到file结构里的file_operations里的具体的read函数来读取文件。write系统调用原理类似。

六. 分析Linux应用程序性能影响因素

在分析linux程序性能影响因素时需要先确定程序的类型。主要有以下两种:

cpu密集型:例如web服务器像nginx node.js需要CPU进行批处理和数学计算都属于此类型

io密集型:例如数据库常见的mysql,大量消耗内存和存储系统,对CPU和网络要求不高,这种应用使用CPU来发起IO请求,然后进入sleep状态。

确定了应用类型就开始分析有哪些情况能影响性能:

大量的网页请求会填满运行队列、大量的上下文切换,中断。

大量的磁盘请求。

网卡大量的吞吐。

以及内存耗尽等。 

归结起来就是4个方面cpu memory i/o和 network。

 

 这里我选择了nginx来分析性能影响因素,通过在容器内搭建nginx,然后用另一个终端进行大量请求测试发现CPU使用率很高,但是看下面的进程的CPU使用率好像很正常。

这里使用top和pidstat命令来定位问题,发现task任务数量不正常,想到可能是短时间的应用导致的问题,如下面的两个:

(1)应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过top等工具发现不了。

(2)应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用很多CPU资源。

另外通过对nginx大量请求测试可能会出现丢包问题。可以总结为以下几个方面:

在两台 VM 连接之间,可能会发生传输失败的错误,比如网络拥塞、线路错误等;

在网卡收包后,环形缓冲区可能会因为溢出而丢包;

在链路层,可能会因为网络帧校验失败、QoS 等而丢包;

在 IP 层,可能会因为路由失败、组包大小超过 MTU 等而丢包;

在传输层,可能会因为端口未监听、资源占用超过内核限制等而丢包;

在套接字层,可能会因为套接字缓冲区溢出而丢包;

在应用层,可能会因为应用程序异常而丢包;

总之,对于具体的应用程序,我们可以从CPU ,内存, I/O以及网络等几个方面去分析影响性能的因素,利用性能测试工具去定位和解决问题。

 

 



这篇关于Linux操作系统分析_课程学习总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程