Linux操作系统 --- 进程
一、内核
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. 进程隔离
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)