Linux

目录

Linux介绍

程序演变

多核 和 多CPU的区别

设计哲学

用户态和内核态 

中断

Ext2第二扩展文件系统

进程

进程间通信

僵尸进程和孤儿进程

死锁

进程调度算法

线程

进程、线程、协程的区别

虚存管理

虚拟内存的好处 

页面置换算法

内存寻址

socket API

一些问题

IO多路复用

常用Linux命令


Linux介绍

程序演变

  • 单道程序:一次运行一个程序
  • 多道程序:OS控制程序切换,'同时'运行多个程序,基于时间片切换进程
    • 资源利用:IO等待时,可以让其他程序执行
    • 公平:多用户、多程序基于时间片交替执行
    • 便捷:多进程一个完成一种任务通过交互,而不是一个程序完成全部任务
  • 多线程:多CPU场景下,一个进程只能占用一个CPU会浪费
    • 简化建模:更贴近人日常行为,等待水开时读报
    • 简化请求处理

多核 和 多CPU的区别

  • 多核是一个CPU里有多个计算引擎,可以让多线程并行工作;
  • 多CPU是多个CPU,可以多进程并行工作
    • CPU内含Cache和MMU(分页内存管理单元,处理虚存映射的)
    •  所以多CPU有多个地址空间,可以让多进程并行

设计哲学

  • 一切皆文件;
  • 单一职责,每个程序只做好一件事,复杂的功能通过程序间协作实现;
  • 内核态、用户态,通过系统调用提高超过用户权限的功能;
  • 使用小写字母并尽量短

用户态和内核态 

  • 出于资源分配、安全考虑,CPU有特权级别(0,1,2,3),不同级别能访问不同资源,Linux只用了0和3,就是内核态、用户态
  • 地址空间可以分为内核空间和用户空间,用户代码无权访问内核空间、底层硬件,需要访问时,通过系统调用切换到内核态时,CPU进入0级特权,使用内核栈执行内核代码来完成

常见系统调用

  • 进程控制、文件系统、系统控制、内存管理、网络管理、socket管理、用户管理、进程间通信

中断

  • 作用:允许暂停当前任务,转而去执行更紧急的任务
  • 流程:
    • 收到中断源发出的中断请求
    • 保护现场(现在执行的程序的执行上下文)
    • 调用对应的中断处理程序进行处理
    • 关中断,恢复现场
    • 中断返回

Ext2第二扩展文件系统

  • 为文件预分配磁盘块,使得文件拓展时避免了磁盘碎片
  • 对磁盘块分组,将同组磁盘块放到相邻磁道内,减少平均寻道时间,局部性原理
  • 支持只读、只追加文件

注:磁盘类似一个多个光盘插到一个转轴上,磁道就是每一个光盘,每个磁道分扇区

 

进程

进程状态:新建->就绪(除了CPU其他资源都齐全了)->运行->等待(等待所需资源释放)->终止(可以被释放了)

进程间通信

运行在同一OS中的不同进程间的消息传递,有些通信需要同步处理

  • 管道:父进程打开一个管道文件,fork后子进程同样能访问同一个管道文件描述符( 父进程关闭读,子进程关闭写,就形成了一条单向通信数据流)      
  • FIFO(具名管道):有一个路径名与之关联,因此允许无亲缘关系的进程访问同一个FIFO
  • 消息队列
  • 共享内存:将同一块物理内存映射到通信双方的地址空间(效率最高,需要加锁)
  • 同步(互斥量、条件变量、读写锁、文件和记录锁、信号量)
  • socket:双方或多方约定一个端口,用一个监听socket绑定它,然后通信

管道与消息队列的区别

  •  管道最后一次关闭时,数据会被丢弃,而消息队列具有随内核的持续性
  •  管道传输字节流(没有边界,也没有类型信息),消息队列存的是有格式的消息
  • 管道传输时接收方必须也在场

僵尸进程和孤儿进程

fork的过程:创建一个新进程,与父进程执行相同的代码,拷贝父进程的资源,子进程从fork函数开始执行,子进程fork返回结果为0,父进程fork返回子进程ID,以此做区分,让它们做不同的事

僵尸进程:子进程运行完毕后,父进程没有wait回收其资源

产生原因:Linux提供了一种机制,保证父进程可以取得子进程退出时的状态信息,子进程退出时,内核释放其大部分资源,但保留进程ID、运行时间、退出状态,等待父进程wait(阻塞)来取后才释放

解决方法:杀死父进程,僵尸进程变成孤儿进程,被init进程领养负责回收

孤儿进程:父进程运行完毕,子进程变成孤儿进程

预防措施:

  • 父进程wait阻塞等待子进程完毕后释放资源
  • fork子进程,子进程fork孙进程执行任务,子进程退出,孙进程被Init接管
  • 父进程不在乎子进程结束状态,通过signal通知内核随便处理,内核负责释放资源
  • 父进程通过signal注册handler,等子进程结束后父进程收到信号,在handler里调用wait回收

学习自百度百科 僵尸进程词条  https://baike.baidu.com/item/%E5%83%B5%E5%B0%B8%E8%BF%9B%E7%A8%8B/1036577?fr=aladdin

守护进程:没有控制终端与用户交互,父进程是init进程

为什么浏览器用多进程架构?

  • 端口
  • 更强的健壮性:多线程共享地址空间,容易一个线程的崩溃导致整个应用的崩溃
  • 隔离,更安全:某一个页面出了病毒后不容易危害到其他页面

死锁

  • 四个必要条件:资源互斥、非剥夺、请求保持、循环等待
  • 避免--银行家算法,安全路径

进程调度算法

 短作业优先先来先服务高响应比优先时间片轮转多级反馈队列
   响应比 = (等待时间+运行时间)/ 运行时间 

多个优先级队列,所分配的时间片逐渐增加

进程先到1级,时间片结束后到2级,...

   短作业优先+先来先服务  
      

评估指标:

  • 吞吐量:单位时间完成的任务数
  • 周转时间:等待时间+运行时间,提交任务到执行完任务的时间
    • 平均周转时间:每个进程的平均周转时间
  • 带权周转时间:周转/运行,如果有些任务长时间等待,影响更大
    • 带权平均周转时间

线程

多线程 对于提高并发性的意义:

  • 充分利用多核CPU的特性;
  • 在IO操作繁忙时让出CPU资源

线程间通信

  • 互斥量:实现对共享资源的互斥访问,加锁
  • 信号量:PV操作,实现同步
    • 信号量SV(可以认为是可获得的资源数目)
    • P操作:获取资源
      • if SV>0:SV-1
      • else 挂起当前线程
    • V操作:释放资源
      • if SV>0:SV+1
      • else 唤醒一个挂起线程
  • 条件变量:线程间的通知机制
    • 当条件变量达到某个值时,唤醒等待这个条件变量的线程(1或多)

进程、线程、协程的区别

关系:多线程共享进程的系统资源,一个线程含多个协程 

 进程线程协程
定义进行中的程序轻量级进程,与其他进程共享了系统资源的进程

一个协程是一个函数以及保存函数运行时数据的栈

运行上下文

系统资源:打开的文件表、页表、页目录等

硬件上下文:CPU寄存器(存于tss段)、栈中数据

CPU寄存器、栈(存储执行期间的临时变量)CPU寄存器、栈
切换时的消耗

切换页目录和页表,使用新的虚拟地址空间;

缓存、快表失效;

切换 CPU寄存器、用户栈;

用户态-内核态转变

切换 CPU寄存器、栈

线程调度由内核进行,也涉及内核态转换

切换 CPU寄存器、栈;

用户级的轻量线程,由用户自行调度,内核对此一无所知

 最小系统资源分配单位最小调度单位 

参考自 知乎 为什么协程切换的代价比线程切换低?  

虚存管理

虚拟内存的好处 

  • 安全性:
    • 读写内存的安全性,由于物理内存是随意访问的,通过CPU特权级别和MMU(内存管理单元)的内存保护机制,使虚页在不同特权下有不同访问权限,这样可以保护只读段、内核空间
    • 进程间的地址隔离,防止误操作别的进程的数据
  • 效率:
    • 通过映射可将离散的内存块利用起来,避免有足够空闲空间却无法分配的问题
    • 支持多进程运行,分配的虚拟空间可能远大于实际物理空间,进程的虚页可能映射到内存、硬盘中
  • 虚拟内存地址:多级页表号+页内偏移量,通过查询页表找到内存中对应的页,若查不到则缺页,调页
  • 多级页表好处:时间换空间,通过分级,共享一些高级的位,节约内存,可以实现将页表的部分加载到内存
  • 快表:缓存了部分页表查询结果

学习自 https://blog.csdn.net/u012150590/article/details/51352019

页面置换算法

 LRULFUFIFO
 最近最少使用最少使用频率淘汰最早加载到内存的

内存寻址

  • 地址分类:
    • 逻辑地址:机器指令中的地址
    • 虚拟地址:开启分页时的逻辑地址
    • 线性地址:段页式下的逻辑地址
    • 物理地址:实际内存地址
  • 段页式虚存管理:程序分段,段分页,逻辑地址由 段号-段内页号-页内地址组成
    • 寻址时,去段表寄存器(存段号--段起始地址)根据段号查段的起始地址 
    • 然后根据页号计算出页的起始地址(页是定长)
    • 再去页表里查页映射的物理块的起始地址
    • 然后用页内偏移+物理块起始地址就是访问地址了
  •  所以要3次访问内存:段表、页表、物理内存 

学习自 百度百科

socket API

  • 概述:socket API是Linux内核提供的网络层、传输层、数据链路层协议实现的调用接口
  • 作用:
    • 负责用户空间和TCP/UDP收发缓存区之间数据复制
    • 修改内核各层协议的头部或其他数据结构,精细控制底层通信,如setsockopt设置IP报生存时间
  • socket通信过程:
    • 服务端:
      • 建立socket
      • 创建socket addr(ip,端口)
      • bind绑定(命令socket):将socket与socket地址绑定
      • listen:创建监听队列来存放待处理的客户连接
      • accept:阻塞等待连接建立,返回与客户端连接的socket
      • read, write:通信
    • 客户端:
      • 建立socket(匿名)
      • connect:发起连接
      • close:关闭

listen函数中的backlog是什么意思?设置的意义?

  • 内核会为listen socket维护两个队列
    • 未完成连接的队列:收到SYN发回ACK后的socket,SYN_RECV状态
    • 完成连接的队列:收到ACK完成连接建立
  • 两个队列长度之和>backlog 时,新连接请求会被拒绝
  • 意义:控制处理连接请求的速率

一些问题

  • 为什么进程进行上下文切换时的开销比线程进行上下文开销大?
    • 页表切换、快表失效
  • 线程共享进程的什么资源?
    • 系统资源:文件描述符、地址空间、网络连接
  • 进程和线程使用上的区别?
    • 程序执行需要资源,多进程更安全
  • 多核时多线程优于多进程?
    • 理由1:多线程能利用多核进行并行计算
    • 理由2:多线程共享地址空间,能减少地址切换的开销
  • 进程和线程的区别,为什么进程的创建销毁比线程开销大?
    • 进程是系统资源分配、竞争的最小单位,线程是CPU调度的最小单位
    • 可以认为进程包含多个线程,多线程共享进程的系统资源,如文件描述符、地址空间
      • 线程有独立的栈空间(存储执行期间的临时变量)、一组寄存器值
    • 进程创建时要分配系统资源,销毁时回收资源,如文件描述符、PCB、页表
  • 虚拟内存最大可以到多少?能超过物理内存(比如说4G)的大小吗?能到1TB吗?
    • 32位地址线的话最大是2^32=4G,可以超过物理内存,可以,但是没有意义,因为你的程序也只能访问到2^32个地址单元
  • malloc函数,操作系统是怎么分配内存的?
    • 库会先申请一大块作为内存池,避免频繁系统调用,将它们分成8、16、24、...、256的块,
      • 小内存直接从里面取一块,大的才再申请
  • cache的缓存如何和外存的缓存保持一致性?
    • 写直达:同时向缓存、内存里写
    • 写回:先写到缓存里,当缓存块要被替换时才写回内存
    • 多核时缓存一致性 -- 写传播:写缓存时通过总线广播给其他CPU
  • 共享内存注意的点
    • SHMMAX总体的大小限制
    • 创建共享内存时的key要唯一,key设置为IPC_PRIVATE,由OS保证唯一性,操作系统忽略键,建立一个新的共享内存,指定一个键值,然后返回这块共享内存IPC标识符ID
  •  

IO多路复用

常用Linux命令

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值