【春招预热】操作系统
进程管理
进程
进程是分配系统资源的基本单位,进程控制块PCB描述进程的基本信息和运行状态,创建进程和销毁进程都需要对PCB进行操作。
线程
线程是进行调度的最小单位,是能够独立运行的最小单位。能够并发执行。
哪些东西是线程共有的,独立的 多个线程可以共享进程资源,如地址空间,已打开的文件,定时器,信号量。申请到的I/O设备;线程本身并不拥有系统资源,但拥有独立的线程控制块TCB、程序计数器、局部变量、寄存器、堆栈。
系统开销 进程创建,撤销需要分配进程控制块,分配或回收内存空间和I/O设备;切换进程,涉及上下问切换;由于具有相同地址空间,线程通信同步简单。线程切换,仅需要设置少量寄存器。在一些OS中,线程切换、同步和通信无需操作系统内核的干预(哪些OS?)
多进程和多线程的特点和区别
线程不拥有资源,但是可以访问所属进程的资源;线程共享进程数据,无需分配太多资源,切换开销小,CPU调度的基本单位,快;线程通信可以通过读写公共数据。
进程是分配资源的基本单位;创建销毁,切换复杂,速度慢;进程间通信需IPC。
进程的三种状态:就绪,运行,阻塞
进程调度算法
优缺点是什么?https://leetcode-cn.com/leetbook/read/tech-interview-cookbook/oozipt/
批处理系统:先来先服务,短作业优先,最短剩余时间优先
交互式系统:时间片轮转,优先级调度,多级反馈队列
时间片轮转
从就绪队列中取队首进程,让它运行一个时间片,当时间片用完时,系统发送中断信号,让其暂停执行,将这个进程放如就绪队列队尾。
- 因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。
而如果时间片过长,那么变成了FCFS
多级反馈对列
如果一个进程要执行100个时间片,那么他就要切换100次。
多级队列则设置多个队列,每个队列的时间片大小都不同,这样就可以可以节省交换时间。每个队列的优先级不同,只有优先级高的队列中没有进程等待时,才会执行当前队列队列中的进程。
当前队列没执行完,加入下一个队列。
非抢占和抢占
非抢占式优先权算法,即系统一旦分配处理机后,该进程一直执行,直到完成。一般用于对实时性要求不高的系统。
抢占式即系统会暂停当前运行的进程,让优先级更高的进程执行。一般用于对性能要求较高的批处理系统和分时系统中。
进程同步
临界资源 只允许进程间互斥访问,同一时间内只有一个进程可以访问的资源
临界区 操作临界资源的交临界区。entry->critical->exit
信号量
是一个整形变量。可以对其执行down和up操作。
down 信号量-1,如果为0,进程睡眠
up 信号量+1,唤醒进程让其执行down操作。
down和up都被设置成原语,不可分割,在执行这个操作的时候屏蔽中断。
如果信号量只能为0或者1,那么就是互斥量。0表示加锁,1表示解锁。
进程通信
管道、命名管道、消息队列、信号量、内存共享、套接字Socket
命名管道
去除管道只能在父子进程中使用的限制
#include <sys/stat.h> int mkfifo(const char *path, mode_t mode); int mkfifoat(int fd, const char *path, mode_t mode);
消息队列
- 消息队列可以独立于读写进程存在,从而避免了 FIFO 中同步管道的打开和关闭时可能产生的困难;
- 避免了 FIFO 的同步阻塞问题,不需要进程自己提供同步方法;
- 读进程可以根据消息类型有选择地接收消息,而不像 FIFO 那样只能默认地接收。
共享内存
由于不需要在进程间进行数据拷贝,共享内存方法较快。需要使用信号量来对共享内存进行控制。通信的进程都将共享文件的地址映射到自身地址中。XSI不使用文件,而是用内存匿名段。
操作系统如何停止一个线程
进程调度,内存释放
32,64位操作系统区别
内存寻址
锁
悲观锁:读锁,写锁
乐观锁
互斥锁
条件锁
死锁
如果一组进程都在等待该组进程内的其他进程占有的资源,那么这一组进程死锁。
-
竞争不可抢占性资源引起死锁。
-
竞争可消耗资源
死锁条件
- 互斥条件:一个资源只能被一个进程占用,其他想用的进程只能等待。
- 占有和等待:进程占有资源后可以请求其他资源
- 不可抢占:其他进程不可以抢占,只能等待主动释放
- 循环等待:进程-资源循环链,成环
处理
死锁预防
破坏四个条件
互斥:
占有等待:规定所有进程在开始执行前请求所需要的全部资源。
不可抢占:当一个进程申请获取资源超时,就释放自己的所有资源。
循环等待:给资源统一编号,进程只能按编号顺序来请求资源。
死锁检测
允许死锁发生,即使发现抢救
每种一个资源 画出资源分配图,有环即有死锁
每种多个资源 记录拥有量,请求量,总量
寻找一个没有标记的进程,请求资源小于剩余资源,分配资源并标记。寻找下一个进程。
结束后没有被标记的都是死锁进程。
死锁避免
运行时避免发生死锁
1. 安全状态
允许动态申请,分配前计算安全性,存在某种进程推进顺序,使得所有进程均完成执行,即为安全状态
完成后释放
2. 银行家算法
进程申明最大单元数目,申请资源时判断安全状态。
E 总资源 P 已分配 A 可分配(空闲)
安全性算法:查找右边的矩阵是否存在一行小于等于向量 A。如果不存在这样的行,那么系统将会发生死锁,状态是不安全的。
假若找到这样一行,将该进程标记为终止,并将其已分配资源加到 A 中。
重复以上两步,直到所有进程都标记为终止,则状态时安全的。
死锁恢复
-
允许抢占
-
回滚到之前,还没有占用那个资源的检查点,
假设,检测到进程1与进程2构成死锁.进程1需要的资源A此时被进程2占用.我们准备通过重新分配资源满足进程1,从而消除死锁.此时,我们需要检查进程2的检查点,将其恢复到某一检查点文件上, 在该检查点上,进程2尚未占用资源A. 通过对进程2进程复位,其在检查点后的所有工作将被清除.然后我们可以把资源A分配给进程1.如果复位后的进程2试图重新获得对该资源的控制,它必须等到该资源可用时为止, 至少需要在进程1执行完毕并释放该资源后.
-
杀死死锁进程
存储
存储器层次结构
寄存器
高速缓存
主存(DRAM)
磁盘
(远程二级存储,服务器,分布式系统)
越往上,越快,价格越高
LRU算法和实现
删除最近最少使用的缓存数据。
使用链表和哈希表实现。https://leetcode-cn.com/problems/lru-cache/
操作系统如何申请内存
两个系统调用:brk 和 mmap
虚拟存储器
一种将主存用作辅助存储器高速缓存的技术,对内存空间做逻辑上的扩充。
允许云计算在多个虚拟机之间有效安全地共享存储器;消除小而受限的主存容量对程序设计造成的影响
分页和分段
- 虚页号和页偏移,页偏移域决定了页的大小
- 段号和段内偏移:段大小可变,需要进行边界检查以确定偏移量是否在段内
PAE技术(虚拟地址扩展)
一般情况下来说,32位系统无法访问4G以上的空间,但是PAE将地址拓展到36位。采用三级页表,2Mb的page
Linux
查看进程、内存情况
ps命令
ps -aux | grep pid 用来查看某进程的状态
ps -ef | grep 查询id,然后kill:kill -9 1234
-2 中断 ctrl C 安全推出关闭;保存相关数据,然后再退出
-9 表示无条件退出,不会主动释放资源
-15 释放资源后关闭
ps -A 显示所有进程
free命令 free -m,查看内存的使用情况
top
查询进程信息、查看内存使用情况
解压
tar指令解压文件
五选一必选
-c 简历压缩档案 -x 解压 -t 查看内容 -r 向压缩归档文件末尾追加文件 -u 更新原压缩包的文件
可选
-z 有gzip属性 -j 有bz2属性 -Z 有compress属性 -v 显示所有过程 -0 将文件解开到标准输出
文件权限
linux文件基本权限九个,ower/group/others,三种身份各有自己的read/write/execute
修改指令 chmod
rwx分别为4 2 1,三项累加,如-rwxrwx---,则为-770
chmod -R 770 test.c
-R为递归持续变更,同目录下的文件都会变更
说说常用的linux命令
ls 查看当前目录的文件
cd 进入一个目录
grep 分析一行的信息,如果包含我们所需要的信息,就显示出这一行,通常与管道一起使用
cp :复制
mv 移动
rm 删除
kill 向进程发送终止信号
tar解压
cat 查看文件内容
pwd 显示工作目录
动态链接和静态链接
ar创建库文件
动态库 汇编-fpic -shared生成位置无关代码
库小:使用静态库,大时使用动态
静态库 .a
-
打包到应用程序中加载速度快;无需提供库,已经在可执行程序中,移植方便
-
消耗系统资源,代码打包多次;更新部署发布麻烦
动态库 .so
- 加载到内存中,实现(进程间)资源共享
- 更新部署发布简单
- 可以控制何时加载动态库
- 加载速度慢;需要提供依赖的动态库
内核态/用户态
内核态(系统态)拥有最高的权限,可以进行一切指令执行和文件操作权限。而用户态只能访问一部分指令。
进入内核态 系统调用,异常,设备中断。系统调用是主动进入,后两者都是被动进入。
区分的原因 用户程序可能是攻击性的,为了安全,需要做隔离机制。防止一些危险指令被恶意操作,如清空内存,设置时钟等。
虚拟内存
操作系统为每一个进程分配独立的地址空间,即虚拟内存。
为什么使用虚拟内存
- 虚拟内存提供空间隔离,保护数据不被随意修改
- 内存的使用效率较低
- 运行时的地址不确定,操作系统随机为程序分配内存空间
优点
- 扩大地址空间,每个进程4G,虽然实际上不用那么多
- 内存保护,防止恶意篡改
- 实现内存共享,方便进程通信
- 避免内存碎片。物理内存不一定连续但是虚拟内存上可以连续。
缺点
- 页表额外空间
- 换出页面耗时,转换地址耗时
页表
每个程序都拥有自己的地址空间。操作系统将虚拟内存映射到物理内存的表即为页表。
虚拟空间地址被划分成有独立地址空间的段(分段),每个段上划分成相同大小的页(分页)
系统启动时,操作系统将整个物理内存划分成固定大小的页。Linux实现分级页表,可以减少内存消耗。
虚拟地址
虚拟地址包括:虚拟页号,页内偏移
GDB调试
next 下一条语句,不会进入函数
step into 进入函数
list 查看源代码
quit 结束
多进程调试
set follow-fork-mod child 子进程
set follow-fork-mode parent 父进程
小端大端
小端:高字节在高地址(0x12345678分别放在0x4003 0x4002 0x4001 0x4000)
大端:高字节在低地址(字符串处理,0x12345678分别放在0x4000 0x4001 0x4002 0x4003)
大端比较符合直觉
小端机:x86 ARM
大端机:网络字节序
存一个整数,然后用指针来访问地址内容即可。
short int x; char x0,x1; x=0x1122; x0=((char*)&x)[0]; //低地址单元 x1=((char*)&x)[1]; //高地址单元
网络字节序
网络通信时是否需要进行字节序转换
同平台不需要转换,但跨平台一定需要转换。否则双方发送接收了正确的数据,却没有按照正确的字节序来读取。
网络字节序 网络上传输的都是字节流。UDP/TCP/IP协议规定:把收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节。网络字节序要求大端序,小端存放的数据发送前需要用系统提供的转换函数 htonl()
转化为大端发送
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】