目录
- 大端小端规则判断
- 磁盘调度算法
- 计算机的启动过程
- 用户态和内核态
- 为什么要区分用户态和内核态
- 如何从用户态进入内核态
- 系统调用的过程
- 进程与线程
- 协程
- 线程之间什么是共享的,什么是不共享的
- 进程切换的具体过程
- 僵尸进程和孤儿进程
- 父进程如何知道子进程的存亡, 子进程如何知道父进程的存亡
- 守护进程
- copy-on-write 写时复制
- 进程间通信方式:
- 线程间通信方式:(实现线程同步|线程同步互斥的4种方式)
- 线程同步和互斥的区别
- 产生死锁的条件(全)
- 死锁的解决策略
- 生产者消费者问题
- 哲学家就餐问题
- 读写者问题
- 几种典型的锁
- 常见的六种进程调度算法
- 一个进程可以创建多少线程,和什么有关?
- 多进程架构与多线程架构有什么区别
- 为什么线程多用于IO密集型场景
- 原子操作如何实现
- 分段存储和分页存储的区别以及优缺点
- 地址变换中,有快表和没快表,有什么区别?
- 页面置换方法
- 虚拟内存
- 虚拟内存的好处
- 虚拟内存的代价
- 抖动你知道是什么吗?它也叫颠簸现象
- 缺页中断
- 缺页中断与一般中断的主要区别
- 内存溢出与内存泄漏
- 伙伴系统(是连续存储分配的一种办法)
- reactor和proactor
大端小端规则判断
大端模式: 指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中
小端模式: 指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中
为什么会有大小端之分呢?
因为在计算机系统中,我们以字节为存储单元,每个地址单元都对应着一个字节,一个字节为8bit。而在C语言中,不仅仅是一个字节来存储一个数据,除了一个字节的char,还有两个字节的short,四个字节的int等等(看具体编译器)。另外,对于位数大于8位的处理器,例如32位的处理器,由于寄存器的宽度大于一个字节,那么就有如何将多个字节进行排布的问题,于是就出现了大小端的问题
一般网络字节序为大端字节序,主机字节序为小端。
磁盘调度算法
1. 先来先服务(FCFS)
按照磁盘请求的顺序进行调度。
优点是公平和简单。缺点也很明显,因为未对寻道做任何优化,使平均寻道时间可能较长。
2. 最短寻道时间优先(SSTF)
优先调度与当前磁头所在磁道距离最近的磁道。
虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥饿现象。
3. 电梯扫描算法(CSCAN)
电梯总是保持一个方向运行,直到该方向没有请求为止,然后改变运行方向。
电梯算法(扫描算法)和电梯的运行过程类似,总是按一个方向来进行磁盘调度,直到该方向上没有未完成的磁盘请求,然后改变方向。
因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了 SSTF 的饥饿问题。
计算机的启动过程
第一步: 读取bios,进行通电自检,然后按照设定好的启动顺序,交付cpu控制权
第二步:
-
bootsect阶段
操作系统存在于磁盘中,将其载入到内存中。
-
setup阶段
完成操作系统启动前的设置,读取硬件参数,比如物理内存大小,显卡参数等等。构造硬件参数的数据结构,以便对硬件进行管理。将操作系统处于0地址处。
-
进入保护模式,切换内存寻址方式
-
运行操作系统
用户态和内核态
用户态: 应用程序只能在用户态运行——运行用户程序
内核态 操作系统在系统态运行——运行操作系统程序
为什么要区分用户态和内核态
限制不同的程序之间的访问能力, 防止获取系统的所有内存数据
如何从用户态进入内核态
用户态切换到内核态的唯一途径——>系统调用/中断/异常(缺页异常)
内核态切换到用户态的途径——>设置程序状态字
系统调用的过程
概念:
应用程序可以发出系统调用请求来获得操作系统的服务
首先运行于用户态的应用程序发出系统调用请求,保护现场。一般都是给出一个中断指令(软中断),然后根据中断向量表查找系统调用表,最后在核心态执行系统调用处理程序(中断程序),最后返回应用程序,恢复现场。
进程与线程
根本区别: 进程是操作系统资源分配的基本单位,而线程是CPU任务调度和执行的基本单位
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程
(2)进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.(同一进程的所有线程共享该进程的所有资源)
(3)进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。
而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
(4)线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。
(5)多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
线程好处:
(1)易于调度。
(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
(3)开销少。创建线程比创建进程要快,所需开销很少。
(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
协程
协程是用户态的一种轻量级线程,协程拥有自己的上下文和栈,协程调度时可以把上下文和栈保存在其他地方,协程能保留上一次调用时的状态,再次运行时能直接进入上次的状态。
协程的好处:
- 无需线程上下文切换的开销
- 无需原子操作锁定及同步的开销
- 方便切换控制流,简化编程模型
线程之间什么是共享的,什么是不共享的
堆,全局变量,静态变量是共享的。
栈与寄存器是不共享的。
进程切换的具体过程
进程的切换发生在内核态,首先内核会将进程的寄存器状态压入堆栈进行保存,而进程的其他上下文信息都保存在pcb中。
切换全局页表安装一个新的地址空间。
切换内核态的堆栈以及硬件上下文。
僵尸进程和孤儿进程
-
僵尸进程
子进程退出后需要父进程的确认收到才能在进程表中删除,而如果在自己成退出后,父进程并没有对其消亡进行确认,该进程就保存进程表中,占用资源。
- 可以使用
ps aux | grep Z
查看当前的僵尸进程。 - 使用
kill -s SIGCHLD pid
删除该父进程的所有僵尸进程
- 可以使用