linux内存管理部分
- 物理内存、虚拟内存、分段分页、mmu、页表、tlb的基本概念
- 进程的内存模型:栈、文件映射区、栈、data段、bss段、text段
- 物理内存管理:buddy和slab,参考这篇文章
- 虚拟内存管理:brk和mmap,参考这篇文章,申请虚拟内存时还没有分配物理内存,缺页异常时申请物理内存并进行映射。
- 标准库:malloc,通过brk和mmap向操作系统申请内存,为了减少不必要的系统调用,malloc也会管理内存,参考这篇文章
- 用户层:malloc的定位是一个通用型的内存管理器,必须要平衡各种情况。在用户层可以针对特殊场景定制内存池,减少开销(比如定长内存块申请、单线程管理)、便于监控和debug等等。参考这篇文章
进程、线程和协程
- 进程和线程的区别和联系
进程作为资源管理的基本单位,线程作为调度的基本单位,一个进程对应着一个到多个线程。 -
进程切换、线程切换
简述进程切换的流程:- 主动或者被动进入内核:时钟中断或者调用了阻塞的系统调用(进入内核的操作会执行特权级切换,主要是从用户栈切换到内核栈,并保存必要的上下文到内核栈中(比如用户栈地址、下一个指令地址))
- 检测是否需要进行调度:时间片消耗完或者等待在阻塞操作上或者有更高优先级的任务需要执行。
- 从中断返回时会进行检测是否需要进行调度,如果需要则进入调度流程。
- 运行调度算法,得到下一个需要被执行的任务对应的pcb,执行cpu上下文切换(包括页表、寄存器、内核栈、必要时进行tlb刷新、cache失效等)
- 继续执行新的任务。
- 线程切换是否比进程切换开销低,如果是说明低在哪里?
如果是不同进程的线程切换,等价于进程切换,如果是相同进程的线程切换,则对于共享资源(内存)不需要切换,这意味着不需要切换页表和tlb,也不需要使cache失效。如果架构支持ASID,则进程切换也不需要清理tlb。 - 什么是协程?协作式调度、用户态切换
-
相比于异步代码,协程的意义?
- 在付出可控资源的情况下,用同步逻辑写异步代码,降低复杂度(情况复杂的时候异步代码的状态太多了,复杂度太高)。
-
有栈协程
- 独立栈:分配多了浪费空间,分配少了有栈溢出风险。
- 共享栈:切换时需要拷贝栈空间
- 参考这里
-
无栈协程
- 状态机+闭包
- 不能被非协程函数嵌套调用
- 需要编译器支持
- 协程切换为什么比线程切换开销低?
参考这个问题下的回答
linux的任务调度算法
- 对于实时进程:FIFO or Round Robin,对于普通进程:O(n) -> O(1) -> CFS
- 参考 这篇文章
进程间通信
- 参考 这篇文章
- 掌握管道、命名管道、消息队列、共享内存、信号量、信号、socket等多种进程间通信方法的优缺点
- 关于unix domain socket,参考这个回复
进程同步
-
什么是死锁?死锁产生的条件
死锁是指多个进程均持有部分互斥资源并等待获取其他资源,等待关系形成一个闭环,从而永久阻塞的情况。
产生条件:- 资源互斥访问,一个资源同时只能被一个进程访问
- 请求保持,进程在请求其他资源时,保持持有现在的资源
- 不可抢占,当占有资源的进程没有释放时,不能通过抢占的方式获取
- 等待形成环。
linux进程有哪几种状态?
- R 可执行状态
- S 可中断的睡眠状态
- D 不可中断的睡眠状态(不响应异步信号,响应硬件中断),这个状态的意义是保证内核某些操作不被外部打断。
- T 暂停、跟踪状态,通过向进程发送SIGSTOP使其进入此状态,典型:gdb调试
- Z 僵尸状态,进程占有的资源释放完毕,仅task_struct结构还没有被释放,保留了退出码,供父进程获取。当父进程先于子进程退出时,将子进程托管给1号进程,1号进程死循环中等待其子进程的退出事件。
- X 不保留task_struct结构直接退出,典型的如同detach过得线程,这个状态非常短暂。
- 参考这篇文章
进程内存布局-栈帧结构
-
栈-文件映射区-堆-bss-data-text
- 参数
- 返回地址
- old_ebp <- ebp
- 一些保存的寄存器信息
- 局部变量
- ... <- esp
- 参考《程序员的自我修养》这本书
文件io
-
mmap
将内核中的页缓存(page cache)映射到进程逻辑地址空间中(堆和栈中间的部分),通过缺页异常由操作系统负责从文件系统中读写数据,用户直接操作内存。- 典型的动态链接库通过mmap映射到进程地址空间。
- mmap还可以用来在进程间共享内存。通过匿名映射,不需要打开一个文件就能在父子进程间共享内存。
- 参考这篇文章
相关文章
暂无评论...