Linux文件系统内核如何调度并发I/O、处理读写者优先级问题
Linux 并发文件I/O的读写请求调度逻辑
首先明确:Linux 内核没有全局统一的并发I/O调度策略,实际处理顺序和内核版本、启用的I/O调度器、文件访问模式(是否用页缓存、是否加锁)直接相关,针对你给出的R R W R R请求序列,我们分默认场景和特殊场景分别说明:
主流默认场景(高版本内核、常规缓存读写)
从Linux 2.6.32版本开始,内核VFS层默认使用**公平读写信号量(fair rw_sem)**做文件访问的并发控制,避免了旧版本读者优先导致的写者饥饿问题,处理逻辑如下:
- 先到的两个读请求R会被同时并行处理
- 写请求W到达后,会进入等待队列,此时后续到达的两个读请求R不会被允许插队到W前面
- 前两个读请求处理完成后,优先处理写请求W,写完再处理排队的两个读请求
对应你给出的选项1:
(R R ) W (R R) / 无饥饿(方案3),这也是绝大多数常规场景下的默认处理顺序。
特殊场景下的其他处理逻辑
旧版本内核/自定义配置读者优先
如果你使用的是2.6.32之前的内核,或者手动修改了内核参数配置为读者优先的读写锁逻辑,就会出现写者饥饿的情况:
只要还有未处理的读请求,后续新来的读请求都会优先处理,直到所有读请求都处理完成才会调度写请求,对应你给出的选项2:(R R R R ) W / 读者优先。
直写/强制锁串行场景
如果你的请求是O_DIRECT直接I/O、或者对文件加了强制锁(mandatory lock)、或者使用了不支持并发的老旧文件系统,所有读写请求都会被强制串行执行,对应你给出的选项3:(R) (R) (W) (R) (R) / 单次串行执行。
块层调度器的影响
如果请求绕开页缓存直接下发到块层,处理顺序还会受到I/O调度器策略的影响:
- 使用
none调度器时,请求会按提交顺序尽可能直接下发,接近串行逻辑 - 使用
bfq/mq-deadline调度器时,会合并相邻地址的IO请求,同时优先调度低延迟需求的小IO,可能会调整原有请求顺序
内容的提问来源于stack exchange,提问作者Woody.P
相关产品推荐
相关产品推荐

