共计 1150 个字符,预计需要花费 3 分钟才能阅读完成。
Linux IO 子系统
传统 IO(读 / 写)
- CPU copy:用户 buffer => 内核 buffer —————————————-> 拷贝 * 1
- DMA copy:内核 buffer => 硬件 ————————————————> 拷贝 * 1
- 上下文切换:用户态 => 内核态 => 用户态 ————————————-> 上下文切换 * 2
PageCache 技术
Linux IO 栈
- 文件系统层:治理 pagecache
- 块层:治理块设施的 IO 队列,对 IO 申请进行合并、排序
- 设施层:通过 DMA 和内存进行交互,负责数据传输
IO 形式:
- 传统 Buffer IO:磁盘 => pagecache => 用户空间 ————————————————————————-> 拷贝 * 2
- mmaped- IO:磁盘 => pagecache => 映射到用户空间,把 pagecache 映射到用户的地址空间外面 ———–> 拷贝 * 1
- Direct IO:用户态和块 IO 层做对接,放弃了 pagecache,从磁盘间接向用户态拷贝数据;益处:快,DMA 拷贝,本人负责 cache —-> 拷贝 * 1
- Buffer IO:偏移 + 长度
- mmaped IO:数据按页对齐
- Direct IO:读写是底层存储块设施大小的整数倍
Linux 内存
地址空间
- 分段机制:逻辑地址 => 线性地址 GDT(段描述符)
- 分页机制:线性地址 => 物理地址
碎片
搭档零碎:将闲暇页分为 11 个链表,每个链表中页块中间断页的大小别离是 1、2、4 .. 1024
申请:申请 4,看 4
- 有:调配
- 没有:看 8,分成两个 4,将另一半挂到块大小为 4 的链表下
- 开释:看搭档是否闲暇,是则合并
- 劣势:合并时地址只有一位不同,十分疾速定位
slab 零碎:
- slab 层有三个 slab 链表,slab-full、slab-partial、slab-empty
- 每个链表有多个 page,每个 page 都分为若干个 object
劣势:
- 将频繁应用的对象缓存起来,缩小调配、初始化和开释对象的工夫开销,如 PCB、inode、lock
- 缩小搭档零碎调配小块内存造成的外部碎片
Linux 过程与线程
- fork() + exec() = spawn()
- COW => 创立开销只有复制页表和 PCB 块
- fork() => clone( 零碎调用) => do_fork()
do_fork() => copy_process()
- 拷贝 task_struct、内核栈
- 清零
- 共享关上的文件描述符、信号处理函数
- 线程创立指定额定参数:
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
正文完