Linux进程概念
-
冯·诺依曼体系结构:
冯诺依曼体系结构作为现代计算机硬件体系结构,规定了现代计算机应该具有哪些硬件单元
- 输入设备 :键盘,鼠标,图像采集设备 ,声音采集设备
- 输出设备:显示器
- 存储器:内存(内存条)+外存(硬盘)
- 运算器:计算,数据处理
- 控制器:信号发送设备调度
-
操作系统
操作系统:管理计算机上的软硬件资源
系统调用接口:操作系统提供的用户访问系统内核的接口
库函数与系统调用接口的关系:库函数实际上就是对系统调用接口进行的一层封装后的接口
-
进程
进程:运行中的程序
对于操作系统而言,进程就是一个程序运行的描述,通过这个描述,操作系统就可以进行程序的调度运行管理
注意:pcb(程序运行描述)通过程序运行的描述,操作系统就可以调度那个程序可以占用CPU去运行指令
要运行哪个程序,则操作系统找到对应程序的pcb,在pcb取出程序的运行所需信息,加载到cpu上,cpu就开始运行这个程序了
pcb描述信息包括:
- 内存指针:描述程序在内存中存放地址
- 上下文数据:进程执行过程中,CPU处理器中的数据
- 程序计数器:记录程序下一条指令的地址
- 进程ID-pid:进程的唯一标识,相等于我们在学校中的学号
- IO信息:显式的I/O请求、分配给进程的I/O设备(例如磁带处理器)和被进程使用的文件列表
- 进程优先级:相比于其他进程的优先级,(进程调度时使用)
- 进程状态:标识进程的状态
分时机制:多任务操作系统中使用分时机制实现多任务并发处理,轮询处理
并发:轮询处理
并行:同时处理
时间片:CPU处理程序执行的这段时间
进程的简单操作:
创建进程:进程就是一个pcb,是一个task_struct结构体,创建一个进程实际上就是创建了一个task_struct结构体
pid_t fork(void) 创建进程的接口 通过复制调用这个接口的进程(父进程),创建一个新的进程(子进程)
注:fork()函数具有返回值
- 返回值是0 ----子进程
- 返回值>0 返回子进程pid -----父进程
- 子进程复制了父进程,因此往后的代码父子进程都会执行,但因为返回值不同进入不同的if判断
ps -ef查看所有进程信息
ps -aux查看具体的进程信息
linux中的进程状态:
运行态(R):正在运行或者轮转到时间片则能够运行统称为运行态
可中断休眠态(S):可以被中断的休眠状态(满足唤醒条件,或者休眠被中断进入运行态)
不可中断休眠态(D):不能被中断的休眠状态(满足唤醒条件之后才可进入运行态)
停止态(T):程序停止运行的状态
死亡态(X):一瞬即逝
僵尸态(Z):进程已经退出了,不再调度,但是这个进程的资源还没有被完全释放,等待资源处理的状态
注:僵尸进程:
如何产生:子进程先于父进程退出,但是父进程没有关注到子进程的退出,子进程为了保存自己的退出返回值,因此系统不会完全释放子进程的资源,这个子进程进入僵尸状态
子进程退出之后,在进程pcb中保存了自己的退出返回值,在父进程没有关注处理的情况下,子进程的pcb资源是不会被释放的
产生危害:资源泄漏(一种是pcb所占内存资源一直无法被回收,一种是一个用户所能创建的进程数量是有限制的)
解决方案: 处理:退出父进程 避免:进程等待
孤儿进程:父进程先于子进程退出,子进程就会变成孤儿进程,其特性:一直运行在后台,父进程成为1号进程(init进程或systemd进程)
守护进程:运行在后台的一种特殊孤儿进程,独立于控制终端并周期性地执行某些任务,脱离登录会话
成为守护进程:(1)成为孤儿进程 (2)设置新会话 脱离终端
-
环境变量
环境变量:也是一种变量,是一种保存系统运行环境参数的变量;便于运行环境参数的配置,进程之间的数据通信
查看环境变量:env
PATH:程序运行的默认搜索路径 ---在命令行终端中输入命令名称可以直接执行对应名称的程序
- env 查看环境变量
- set 查看所有变量
- echo 查看指定变量
- export 设置环境变量 将普通变量设置为环境变量
- unset 删除变量
环境变量接口:
char *getenv(const cahr* name); --通过名称获取值
shell中运行的程序,父进程都是shell 或者反过来说 shell中运行的进程都是shell的子进程
int main(int argc,char* argv[],char* environ[]) 程序运行参数的个数,参数运行参数字符串地址 环境变量的字符串地址
程序地址空间:进程的虚拟地址空间,操作系统为每个进程对于内存空间的虚拟描述 linux——mm_struct
-
为什么要使用虚拟内存地址?
1,系统会为每一个进程都描述一个假的地址空间,进程访问的都是虚拟地址,访问内存数据的时候,先将虚拟地址转换为物理地址然后访问,
2,系统为每个进程都描述一个完整的,连续的,线性的虚拟地址空间,实际物理内存用的时候再给进程分配
3,给每一个进程虚拟一个地址空间,让进程访问完整连续的地址,但是这些虚拟地址再使用的时候通过页表映射一块物理内存地址,进行访问物理内存,
4,通过映射这种方式,实现数据在物理内存上的离散式存储,提高内存利用率
总结一下:
虚拟地址空间,是系统为每个进程通过mm_struct结构体虚拟的一个地址空间,使用虚拟地址空间的目的是为了让进程能够访问一块连续的完整的地址,并且经过页表映射到物理内存之后,可以实现数据在物理内存上的离散式存储,提高内存利用率,并且在页表中可以进行内存访问控制
虚拟地址如何通过页表获取到物理地址空间?
首先理解内存管理方式
- 分段式内存管理:将地址空间分为多段(代码段,数据段。。。)便于编译器进行地址管理
分段式虚拟地址组成:段号+段内的地址偏移量;在系统中有一个段表:一个个段表项(段号,物理内存段起始地址)
- 分页式内存管理:将地址空间分为很多小块(页)实现数据离散式存储,提高内存利用率
- 分页式虚拟地址组成:页号+页内偏移,在系统内有一个页表(页号,物理内存块起始地址,权限控制,缺页中断位)
- 段页式:将虚拟内存进行分段,在每个分段内进行分页管理,集合了分段分页的优点进行内存管理,现在比较常用的一种管理方式
缺页中断:通过虚拟地址访问物理内存的时候,发现数据没有在物理内存中,为什吗?
原因在于物理内存交换:当物理内存不够用,将物理内存中不活跃的数据,交换到磁盘的交换分区,将空出的内存用于新的数据处理
内存置换算法:LRU--最久未使用