Linux核心编程
# 程序、进程、线程、协程的区别是什么 new
查看答案
# 总述
这个问题的本质是操作系统对资源的分配
# 操作系统资源都有哪些
- 栈(局部变量,函数参数)
- 线程局部存储
- 寄存器(执行流的基本数据)
- 堆(全局变量)
- 函数内静态变量
- 程序代码
- 打开的文件
# 程序
程序只是一组指令的有序集合
# 线程
- 操作系统分配执行程序的最小单位
- 线程切换的顺序保存数据(包含代码)保存程序指针,加载下一个等待执行程序的数据,程序指针
# 进程
- 应用程序的执行副本,是应用程序向操作系统申请资源的最小单位
- 进程只负责分配内存资源,内存隔离
# 协程
- 协程是程序控制,用户态执行的轻量级线程,通过上下文切换完成
- 协程只是通过切换上下文来(程序指针)来切换执行的程序
# 进程几种状态,什么时候相互转换
查看答案
- 就绪,抢到时间轮片转化到执行状态
- 执行,完成时间分片到就绪状态
- 深睡眠,只有资源准备好才能就绪
- 浅睡眠,可以被信号和资源唤醒
- 僵尸,子进程结束,父进程清理
- 停止,暂停ctrlz/fg/cpulimit
# 什么是虚拟内存?
查看答案
# 概念
- 虚拟内存是计算机系统内存管理的一种技术,计算机内存映射给软件使用。
- 它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间)。
- 而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
# 虚拟内存优点
- 扩大了地址空间。无论段式虚存,还是页式虚存,或是段页式虚存,寻址空间都比实存大。
- 内存保护。每个进程运行在各自的虚拟内存地址空间,互相不能干扰对方。另外,虚存还对特定的内存地址提供写保护,可以防止代码或数据被恶意篡改。
- 公平分配内存。采用了虚存之后,每个进程都相当于有同样大小的虚存空间。
- 当进程需要通信时,可采用虚存共享的方式实现。
# 虚拟内存缺点
- 虚存的管理需要建立很多数据结构,这些数据结构要占用额外的内存。
- 虚拟地址到物理地址的转换,增加了指令的执行时间。
- 页面的换入换出需要磁盘I/O,这是很耗时间的。
- 如果一页中只有一部分数据,会浪费内存。
# 虚拟内存、物理内存、共享内存的区别 new
查看答案
# 物理内存
- 相对于操作系统来说的
- 分为内核部分和外部部分
# 虚拟内存
- 虚拟内存是映射到物理内存中的
- 虚拟内存是操作系统分配给进程的内存
- 内存包含代码段,数据段,堆,栈,文件映射区
# 共享内存
- 动态库的内容是共享的
# 虚拟地址、逻辑地址、线性地址、物理地址有什么区别?
查看答案
# 虚拟地址
虚拟地址是指由程序产生的由段选择符和段内偏移地址组成的地址。这两部分组成的地址并没有直接访问物理内存,而是要通过分段地址的变换处理后才会对应到相应的物理内存地址。
# 逻辑地址
逻辑地址指由程序产生的段内偏移地址。有时直接把逻辑地址当成虚拟地址,两者并没有明确的界限。
# 线性地址
线性地址是指虚拟地址到物理地址变换之间的中间层,是处理器可寻址的内存空间(称为线性地址空间)中的地址。程序代码会产生逻辑地址,或者说是段中的偏移地址,加上相应段基址就生成了一个线性地址。如果启用了分页机制,那么线性地址可以再经过变换产生物理地址。若是没有采用分页机制,那么线性地址就是物理地址。物理地址是指现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果。
# 物理地址
虚拟地址到物理地址的转化方法是与体系结构相关的,一般有分段与分页两种方式。以x86 CPU为例,分段、分页都是支持的。内存管理单元负责从虚拟地址到物理地址的转化。逻辑地址是段标识+段内偏移量的形式,MMU通过查询段表,可以把逻辑地址转化为线性地址。如果CPU没有开启分页功能,那么线性地址就是物理地址;如果CPU开启了分页功能,MMU还需要查询页表来将线性地址转化为物理地址,即逻辑地址(段表)→ 线性地址(页表)→ 物理地址
。
# 映射
映射是一种多对一的关系,即不同的逻辑地址可以映射到同一个线性地址上;不同的线性地址也可以映射到同一个物理地址上。而且,同一个线性地址在发生换页以后,也可能被重新装载到另外一个物理地址上,所以这种多对一的映射关系也会随时间发生变化。
# 物理地址虚拟内存寻址过程
# 虚拟内存好处
查看答案
- 内存空间利用率的问题,虚拟内存把不连续的内存当一整块内存分配给程序
- 读写内存的安全性问题,程序操作虚拟内存是无法操作其它程序内存的
- 内存读写的效率问题,方便把超出内存的数据存入硬盘
# 链接池的好处
查看答案
- 资源重用,避免频繁创建释放
- 响应速度更快,避免初始化开销
- 统一管理连接避免连接泄漏
- 新的资源分配手段,能借助连接池管理连接资源
# 页的概念,linux中页的大小
查看答案
linux读取连续内存会更快,所以使用页来管理内存,内存页的大小默认为4k
# 请写出内核线程和用户线程的区别。
查看答案
根据操作系统内核是否对线程可感知,可以把线程分为 内核线程 和 用户线程 。
# 内核线程
内核线程的建立和销毁都是由操作系统负责、通过系统调用完成的,操作系统在调度时,参考各进程内的线程运行情况做出调度决定。如果一个进程中没有就绪态的线程,那么这个进程也不会被调度占用CPU。和内核线程相对应的是用户线程,用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,用户进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。
# 用户线程
用户线程多见于一些历史悠久的操作系统,如UNIX操作系统,不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位的,所以每个线程执行的时间相对减少。为了在操作系统中加入线程支持,采用了在用户空间增加运行库来实现线程,这些运行库被称为“线程包”。用户线程是不能被操作系统所感知的。
引入用户线程有以下4个方面的优势:
- 可以在不支持线程的操作系统中实现。
- 创建和销毁线程、线程切换等线程管理的代价比内核线程少得多。
- 允许每个进程定制自己的调度算法,线程管理比较灵活。
- 线程能够利用的表空间和堆栈空间比内核级线程多。
# 物理地址虚拟内存寻址过程
# 线程的局部变量被访问会造成什么
# 内存分页的目的是什么
查看答案
- 分页用来映射地址空间
- 保证内存隔离
- 降低内存碎片的问题