死锁
构成条件
-
互斥:资源处于非共享状态
-
占有并等待:一个进程至少占有一个资源,但又等待另一个资源
-
非抢占式:资源不可抢占,只能等持有资源的进程完成任务后该资源才会被释放
-
循环等待:p0等待p1,p1等待p2.....
预防死锁:破坏除了互斥以外的其他三个条件中的任意一个
避免死锁:银行家算法
检测死锁:资源分配图
用户态和内核态
根据资源的访问特点分为用户态和内核态
用户态:用户态进程可以直接读取程序文件,但权限较低,当我们需要处理读写磁盘,网络通信等操作时,需要想操作系统发起请求,进入内核态
内核态:拥有访问计算机所有资源的权限,保存IO,内存空间,驱动程序等,但进入内核态需要进行上下文切换和权限检测,所以应该减少进入内核态的次数,提高系统的稳定性
为什么要区分内核态和用户态
如果只有一个内核态,所有程序都必须共享系统资源,导致系统资源的竞争,当操作一些危险指令(内存分配,IO)时也没有权限校验的过程
如何切换?
-
系统调用:用户态主动进行切换,为了去使用内核态才能做的事例如进行磁盘读取文件资源。
-
中断:当外围设备完成请求后,向cpu发送相应的中断信号,cpu会暂停执行下一条即将执行的指令转而去处理中断信号对应的程序,例如磁盘完成读写操作,系统会切换到磁盘读写的中断处理程序中执行后序操作
-
异常:也叫做内中断,在用户态下执行的程序,发生了某些不可知的异常
进程和线程
进程:指计算机中正在运行的一个实例,例如:你打开一次微信就是一个进程
线程:被称为轻量级的进程,是比进程更小的一个运行单元,多个线程共享一个进程内的资源,例如打开微信后会有一个线程专门负责信息的收发。
进程和线程
-
多个线程可以并发处理不同的任务,更有效地利用了多处理器和多核计算机。而进程只能在一个时间干一件事,如果在执行过程中遇到阻塞问题比如 IO 阻塞就会挂起直到结果返回。
-
同一进程内的线程共享内存和文件,因此它们之间相互通信无须调用内核
PCB
进程控制块:每个进程对应一个独立的PCB,当操作系统创建一个新进程时,会为进程分配一个为一个进程ID,由链表和索引表组成,一直存在内核态中,无论进程是否阻塞
信息
-
进程标识符PID
-
上下文数据
-
进程的调度信息
-
进程的控制信息
-
IO状态信息
进程的状态
-
创建:新创建一个进程
-
就绪:即将拿到CPU的控制权
-
运行:进程正在CPU上运行
-
阻塞:正在等待某一个时间而暂停运行
-
结束:进程正在从系统中消失
僵尸进程和孤儿进程
在Linux中子进程通常由fork()系统调用产生,该调用会创建一个新的进程,子父进程之间的运行是相互独立的,他们各自拥有自己的PCB,即使父进程结束了,子进程依旧可以存活,而一个进程通过exit结束后,会释放资源但pcb仍然存活,这些信息只有父进程调用wait方法才会被释放,此时父进程会获得子进程的状态信息
僵尸进程:子进程已经结束,但父进程还在运行,且父进程没有调用wait方法来获取子进程的状态,导致子进程的pcb仍然存在系统中
孤儿进程:父进程已经终止,但子进程还在运行,通常是因为父进程意外终止或是没有及时调用wait导致,为了避免孤儿继承,操作系统会将孤儿进程的父进程设置为init进程(进程号为1),由init来进行回收
如何查看?
使用Top命令,zombie为0说明没有僵尸进程
内存管理策略
-
段式存储:以段来进行分配物理内存,虚拟的内存地址被分为大小不等的段,会造成内存碎片的问题
-
页式存储:将空间分为连续等长的物理页,不会存在外碎片但由于最小分配单位是一页,即使不满一页大小会造成内存浪费,所以会有内碎片的产生
-
段页式存储:结合段式和页式,将内存先分为若干个段,每个段分为大小相同的页
虚拟内存
操作系统提供的一种机制,将不同进程的虚拟内存地址和不同内存的物理地址映射起来,每次程序访问虚拟地址的时候,由操作系统转换为不同的物理地址,不会造成地址冲突
进程调度算法
-
先来先服务
-
短作业优先
-
高响应比优先
-
时间片轮转
-
多级反馈队列
页面置换算法
-
最佳页面置换
-
先进先出页面置换
-
最近最久未使用
-
时钟置换算法
磁盘调度算法
-
先来先服务
-
最短巡道时间优先
-
扫描算法
-
循环扫描算法