【春招预热】操作系统

进程管理

进程

进程是分配系统资源的基本单位,进程控制块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. 竞争不可抢占性资源引起死锁。

    image-20220318162328244

  2. 竞争可消耗资源

    image-20220318162857228

死锁条件

  • 互斥条件:一个资源只能被一个进程占用,其他想用的进程只能等待。
  • 占有和等待:进程占有资源后可以请求其他资源
  • 不可抢占:其他进程不可以抢占,只能等待主动释放
  • 循环等待:进程-资源循环链,成环

处理

死锁预防

破坏四个条件

互斥

占有等待:规定所有进程在开始执行前请求所需要的全部资源。

不可抢占:当一个进程申请获取资源超时,就释放自己的所有资源。

循环等待:给资源统一编号,进程只能按编号顺序来请求资源。

死锁检测

允许死锁发生,即使发现抢救

每种一个资源 画出资源分配图,有环即有死锁

每种多个资源 记录拥有量,请求量,总量

image-20220318163320713

寻找一个没有标记的进程,请求资源小于剩余资源,分配资源并标记。寻找下一个进程。

结束后没有被标记的都是死锁进程。

死锁避免

运行时避免发生死锁

1. 安全状态

允许动态申请,分配前计算安全性,存在某种进程推进顺序,使得所有进程均完成执行,即为安全状态

image-20220318164517674

完成后释放

2. 银行家算法

进程申明最大单元数目,申请资源时判断安全状态。

image-20220318171727094

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/

操作系统如何申请内存

两个系统调用:brkmmap

虚拟存储器

一种将主存用作辅助存储器高速缓存的技术,对内存空间做逻辑上的扩充。

允许云计算在多个虚拟机之间有效安全地共享存储器;消除小而受限的主存容量对程序设计造成的影响

分页和分段

  • 虚页号和页偏移,页偏移域决定了页的大小
  • 段号和段内偏移:段大小可变,需要进行边界检查以确定偏移量是否在段内

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() 转化为大端发送

posted @   FushimiYuki  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示