进程
系统编程阶段:进程概念->进程控制->基础IO->进程间通信->进程信号->多线程
1.进程概念:
冯诺依曼体系—现代计算机硬件体系结构
输入设备:键盘
输出设备:显示器
存储器:内存
运算器:CPU-中央处理器
控制器:
输入设备—>存储器—>输出设备
||
CPU
所有的硬件都是围绕存储器工作
硬件结构决定软件行为:
操作系统
操作系统的目的:方便用户,让计算机更加好用
操作系统的定位:一款搞管理的软件-管理软硬件资源,提供良好的执行环境
如何管理:先描述,在组织。管理者并不需要直接与被管理者交互进行管理,而是通过对被管理者进行描述,并且将描述信息得当的组织起来进行管理。
库函数与系统调用的关系:
Shell函数,库函数是对系统调用接口的封装,上=是上下级调用关系
进程概念
进程是什么:进程就是运行起来的程序—用户层面的理解
从操作系统的层面理解:
程序运行需要将代码数据加载带内存中
操作系统上运行了很多程序,操作系统就必须去管理这些程序的运行,先描述在组织进行管理,在操作系统的层面进程就是操作系统对一个运行的程序的描述。
校长眼里看到了同学们的档案就仿佛看到真人,通过档案来管理学生
在操作系统眼中看到了对运行程序的描述就仿佛看到了进程,通过描述管理学生
这个描述信息—叫PCB(进程控制块)—Linux下是结构体: task_struct
CPU分时机制:对程序运行处理进行切换调度处理,目的就是为了让所有的程序都能够同时推进
时间片:CPU在每个程序上所运行的这段时间
PCB中的描述信息:
内存指针,程序计数器,上下文数据,标识符PID,进程状态,进程优先级(CPU资源的优先分配),记账信息,IO信息
2.进程查看
查看进程
ps -aux / -ef 都可看进程信息,这是详细度不同
/proc
获取进程ID:getpid()
创建进程
fork()函数创建子进程
创建子进程的意义何在:分摊任务处理压力,让子进程完成其他任务—背锅
如何让子进程完成其他任务
分辨出父子进程
返回值:
对于父进程来说,fork返回值是子进程的PID;创建子进程失败返回-1
对于子进程来说,fork返回值是0
用户通过fork的返回值不同对父子进程运行流程进行分流
复制:操作系统通过复制父进程创建子进程,因此父子进程数据独有,代码共享
进程状态
运行,就绪,阻塞
Linux下进程的状态:
运行:R 拿到时间片即可运行,或者正在运行
可中断休眠:S 可被简单操作唤醒
不可中断休眠:D 磁盘休眠,特定方式唤醒,睡够了才醒,即通常等待io调用结束
停止:T (kill后无返应只有当唤醒时,才显示杀死)kill -9 可以直接杀死
僵死:Z
僵尸进程:处于僵死状态的进程----资源泄露
僵尸进程的产生原因:
子进程先于父进程退出,因为要保留推出原因,因此操作系统不能直接释放所有资源,通知父进程获取推出原因,允许操作系统释放资源,但是父进程没有关注到这个通知,系统无法释放资源,导致处于僵死状态成为僵尸进程
僵尸进程的危害:导致资源泄露
如何避免:进程等待
处理方式:退出父进程
孤儿进程:父进程先于子进程退出,子进程成为孤儿进程,运行在后台,父进程成为1号进 程
守护进程/精灵进程:特殊的孤儿进程
3.环境变量
存储系统运行环境参数的变量
查看环境变量:env set echo $PATH
设置环境变量:export 删除环境变量:unset
常见环境变量:HOME PWD SHELL PATH
环境变量特性:全局特性(继承)
shell终端下所运行的进程能够获取到所有的环境变量,但是获取不到普通变量
环境变量在代码中的获取:
char* getenv(char* name)
main的都三个参数main(int argc,char* argv,char** env[])
extern char** environ 声明全局变量 遍历environ[i]
环境变量的使用场景:通常是父进程通过给子进程设置环境变量来达到向子进程传递数据的功能
4.程序地址空间
内存地址:就是内存区域的一个编号
虚拟地址—虚拟地址空间 struct mm_struct
每个程序都需要连续的地址空间
虚拟地址如何存储数据
虚拟地址空间又是什么?
我们所看到的程序地址空间实际是一个虚拟地址空间,实际上是操作系统通过mm_struct这个结构体为进程描述的一个空间,因此有时候也称作内存描述符
为什么要使用虚拟地址空间呢?
1.进程再通过访问虚拟地址进而获取变量数据,最终还是要去访问物理内存,因为数据是存储在物理内存中的,在虚拟地址和物理地址之间通过页表进行地址映射,转换得到物理地址,进而访问物理内存区域,通过映射以后,物理地址可就不一定连续了,通过这种映射转换的方式实现数据的离散存储提高内存利用率页表中不但记录了虚拟地址和物理地址的映射关系,并且还记录了这块地址的属性实现内存访问控制
2.程序运行需要连续的内存,导致内存利用率低,缺乏内存访问控制,进程独立性低,针对物理内存进行离散存储,提高利用率;为了能够让进程依然认为内存连续;操作系统通过mm_struct单独针对每个进行描述了内存信息;每个进程都认为自己拥有连续的地址空间(实际上是虚拟地址),为了能够让进程通过虚拟地址访问到物理内存;因此又推出页表记录虚拟地址和物理地址映射关系,并且在页表中对内存的访问进行权限控制。
**创建子进程都发生了什么?
创建子进程都发生了什么?
**写时拷贝技术:**操作系统通过复制父进程创建子进程,子进程初始时与父进程指向同一块物理区域,当内存数据发生改变时,会为子进程重新开辟内存更新页表。
进城的独立性:相互不会影响,增强鲁棒性
虚拟地址空间和页表有什么用:提高内存的利用率,增加内存访问控制,保持进程独立性。
页表如何将虚拟地址转换为物理地址
分段式内存管理:
内存地址的构成:段起始地址+段内偏移
段表—有很多的段表项(物理段的起始地址)
通过地址中的段号去段表中找到段表项,通过段表项中的物理段起始地址加上地址中的段内偏移获取到物理地址
分页式内存管理:
内存地址的构成:页号+页内偏移
页表—有很多页表项
通过地址中的页号去页表中找到页表项,通过页表项中的物理页号加上页内偏移获取到物理地址
段页式内存管理:
内存地址:段号+段内页号+页内偏移
段表项中又段内页表起始地址
段内页表项中又包含物理页号
通过段号在段表中找到段表项,通过段表项中的段内页表地址找到段内页表,通过地址中的段内页号在段内页表中找到页表项,通过页表项中的物理页号与页内偏移组成物理地址。
内存置换算法:
内存只有4G,但是想要处理5G的数据
swap又叫交换内存,内存不够时,将内存中的数据置换到交换分区中,腾出内存处理数据
将暂时不用的数据置换到交换分区,获取一部分内存
FIFO:先进先出
LFU:最近最少频率未使用
LRU:最近最久未使用