一、内核

os:内核+其他程序

内核:Linux操作系统的核心,是计算机硬件与上层应用程序之间的核心接口与资源管理者。主要负责进程管理、内存管理、文件系统、设备管理、网络管理。直接运行在硬件之上,掌握所有系统资源,为用户程序提供安全、高效的运行环境

五大核心子系统:

1. 进程管理

1)负责进程/线程的创建、调度、销毁

2)采用CFS分配CPU时间片,CFS通过维护每个进程的虚拟运行时间,让所有可运行进程尽可能公平地获得CPU时间

3)提供进程间通信(IPC):信号、管道、消息队列、共享内存

2. 内存管理

1)管理物理内存与虚拟内存

2)通过分页机制实现虚拟地址到物理地址的映射,负责页表管理、缺页异常、页面置换、malloc内存分配

3)支持交换分区(Swap),缓解内存不足

3. 虚拟文件系统

1)遵循“一切皆是文件”的设计哲学

2)为ext4/XFS等各类文件系统提供统一接口

3)管理文件、目录、权限及磁盘I/O缓存

4. 设备驱动

1)内核代码量占比最大(约50%)

2)管理字符设备(eg:键盘、鼠标)、块设备(eg:硬盘、U盘)、网络设备

3)提供硬件抽象、使应用程序无需关心硬件细节

5. 网络协议栈

1)完整实现TCP/IP协议簇

2)处理数据包的发送、接受、路由与转发

3)为应用提供Socket接口

二、进程

1. 定义:进程是程序的一次运行过程,是操作系统进行资源分配和调度的基本单位 (内核pcb数据结构对象 -- 描述进行的所有属性 + code&&data)

2. PCB

1)Linux用task_struct结构体实现PCB

     内容分类:a.标识符 -- 描述本进程的唯一标识符,来区别其他进程

                      b.状态 -- 任务状态、退出代码、退出信号等

                      c.优先级 -- 先对于其他进程的优先级

                      d.程序计数器 --  程序中即将被执行的下一条指令的地址(程序计数器保存在CPU寄存器中)

                      e.内存指针 -- 包括程序代码和进程相关数据指针,还有堆指针、栈指针、共享库指针、环境变量指针

                      f.上下文数据 -- 进程执行时处理器的寄存器中的数据

                      g.I/O状态信息 -- 包括显示的I/O请求、分配给进和被进程使用的文件列表

                      h.记账信息 -- 可能包括处理器时间总和、时间限制、记帐号等

                      i.其他信息:

3. Linux如何组织进程

在内核源代码中找到,Linux采用双向链表+红黑树+哈希表组织进程,底层遍历task_struct

4. 查看进程

1)/proc

2)PID -- 当前进程ID

     kill -9 PID -- 结束进程 kill发送信号,-9:SIGKILL不能被捕获(kill -l 可以查看所有的结束指令)

     getpid() -- 库函数,获得PID

3)PPID -- 父进程ID

     getppid() -- 库函数,获得PPID

     bash -- 命令行进程 PID∈PPID (PID,PPID是标识符)

5. 创建进程

1)fork() -- 库函数 -- 代码层面

     a. 为什么fork给子程序返回0?

         返回不同返回值,为了区分不同的执行流去执行不同的执行代码块。一般而言,fork之后代码父子共享(代码不可被修改)

   父进程返回子进程PID  子进程返回0  失败返回-1

     b. 为什么fork给父进程返回ppid?

         父进程通过子进程pid控制不同的子进程,子进程返回0因为子进程没有必要知道自己的PID,而父进程需要通过返回值获得子进程PID

     c. fork是如何返回两次?如何理解?

         父子共享代码,fork之后,父进程执行一次fork,产生子进程,父进程继续执行,子进程继续执行

      d. 一个变量为什么会有不同的内容?如何理解?

          任何平台,进程运行具有独立性。子进程进行数据层面的写时拷贝(子进程想访问父进程的某些数据,os在内存中开辟一块空间将父进程的某些数据拷贝过来,让子进程进行访问)

2)./  运行程序 -- 指令级别

3)父子进程被创建好,fork() ,谁先运行由调度器决定,不确定

6.进程状态

1)运行态 --- running --- R

     如何查看进程是否处于运行态( 查看pid的方法 )

     R+ --- 前台运行

     处于运行队列的进程正在运行或者等待CPU调度

2)阻塞状态 ( eg: scanf 函数被调用却不输入,处于阻塞状态)

      定义:等待资源的进程且处于等待队列中的进程

      A. 浅度睡眠 --- sleeping --- S 可中断睡眠 --- 可被信号唤醒

      B. 深度睡眠 --- disk sleep --- D 不可中断睡眠

 无法被删除,不可中断睡眠,通常等待磁盘IO(原因:防止IO过程中被打断导致数据异常)

3)暂停状态 --- T

     A. stopped

     B. 高IO状态 + tracing

4)终止态 --- dead --- X

     运行结束,已经死亡状态,短暂存在,马上释放

5)僵尸状态 --- Z

     进行运行结束,先进入 Z 状态,子进程退出

     若父进程没有主动回收子进程信息,子进程会处于 Z 状态,进程相关资源尤其 task_struct 结构体无法被释放 ( 会被一直占用导致内存泄漏 )

     父进程先退出,子进程的父进程会被改写为1号进行( 由操作系统完成 )

     父进程是1号进程,会导致孤儿进程,该进程被系统领养

     领养进程:孤儿进程也会退出,也要被释放

6)挂起状态

     定义:为了节省内存,等待的进程中代码和数据被换出到外设(磁盘)中,等到被运行时,被换入内存中

7. 进程优先级 priority

nice --- 优先级的修正数值

优先级可以通过 nice 的取值被调整

nice越小,优先级越高

priority(new) = priority(old) + nice

priority(old)取值范围:[100, 139] nice的取值范围:[-20, 19] renice可以更改nice值

8. 其他概念

1)竞争性:

     系统进程数目多,CPU资源少量,进程间存在竞争性,为了高效完成任务,更合理竞争相关资源 --> 优先级

2)独立性:

     多进程运行且互不干扰

3)并行:

     多个进程在多个CPU下分别同时进行运行

4)并发:

     多个进程在一个CPU采用进程切换的方法,在一段时间内,使多个进程都得以推进

9. 其他问题

1)系统通过程序计数器pc,eip( 记录当前进程正在执行指令的下一行指令的地址 )来得知进程执行到哪行代码

2)进程在被切换的时候: --- 防止数据丢失

     保存上下文

     切换上下文

保存:当前进程CPU上下文到PCB中

加载:新进程PCB -> 恢复寄存器 -> 继续运行

3)命令行参数:

     为指令、工具、软件等提供命令行选项的支持

     让不同选项表示不同功能

     两张核心向量表:命令行参数表 环境变量表

     执行命令

     bash本身在启动的时候,会从os的配置文件中读取环境信息,子进程会继承父进程的环境变量

     本地变量 - 在命令行定义的变量 = 变量值

     本地变量不会被子进程继承,只有在本bash内部有效

     export + 变量名 = 变量值 --> 成为环境变量

     set --- 查看系统中定义的所有变量

     命令行上所有指令不一定会创建子进程

     命令:常规命令 --- 通过创建子进程完成  内建命令 --- bash 不创建子进程,自己亲自执行 ( 类似于bash调用自己写的/系统提供的函数)

10. 环境变量 --- 系统提供的一组 name = value 形式的变量,不同环境变量有不同,用户通常有全局属性

环境变量是操作系统提供的一种机制,用于向进程传递运行环境信息,本质是一组由Shell创建并维护的字符串键值对

形式: 变量名 = 变量值

1)echo $PATH

2)PATH:Linux系统

     PATH = 路径(会覆盖) PATH = $PATH(新增且不覆盖)

3)HOME

     $HOME : 当前用户家目录

4)env

     查询环境变量

     unset --- 清除环境变量

5)HISTSIZE --- 记录的历史命令

6)OLDPWD --- 当前路径的上一层

7)PWD --- 当前所处路径

8)SHELL $SHELL 当前默认登录SHELL程序路径

9)USER $USER --- 查看当前登录用户名

10)通过第三方命令行和C语言中 extern char **environ,获取 <unisted.h>

11)bash -> fork() -> 子进程 -> 继承环境变量 -> exec() -> 新程序运行 -> main(argc, argv, env)

11. 进程地址空间 --- 进程地址空间是操作系统为每个进程抽象出来的一段虚拟地址范围

1)地址空间:地址总线排列形成的地址范围 [0, 2^32]

2)本质:内核的一个数据结构对象,类似PCB一样,地址也要被操作系统管理 ,先描述,再组织

      为什么要有:

     A. 让进程以统一的视角看待内存

     B. 增加进程虚拟空间可以让用户访问内存的时候,增加一个转换过程对寻址进行审查,异常拦截保护内存

         进程 = 内核数据结构 + 可执行代码和数据

         页表: 虚拟地址 物理地址 标志位( rlw )

         标志位:对应的代码、数据是否被已经被加载到内存 代码只能读,不能改的原因

     C. 地址空间和页表的存在将进程管理模块和内存管理模块进行耦合

     D. 进程隔离

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐