本文共 1655 字,大约阅读时间需要 5 分钟。
块设备和字符设备是操作系统中常见的硬件设备类型,它们在功能和使用方式上有显著区别。
块设备是指能够随机访问固定大小数据片的硬件设备,这些数据片称为块。最常见的块设备是硬盘。与之相反,字符设备按照字符流的方式进行有序访问,常见的字符设备包括串口和键盘。
两者的主要区别在于是否可以随机访问数据。块设备的管理比字符设备更为复杂,因为块设备需要精确控制访问位置,而不仅仅是控制当前位置。内核中对块设备的管理也比字符设备细致,需要一个专门的子系统来提供服务,这是因为块设备的操作对性能要求更高,每一次操作都可能影响整个系统的运行效率。
在块设备中,最小的可寻址单元是扇区。扇区是设备的物理属性,块设备无法比扇区还小。软件的最小逻辑可寻址单元则是块。块是文件系统的基本抽象单位,文件系统只能基于块来进行操作。尽管物理磁盘的寻址是以扇区为单位进行的,但内核执行的磁盘操作都是基于块进行的。
扇区和块的关系是扇区是设备的最小可寻址单元,块不能比扇区还小,只能是扇区的倍数。因此,块设备需要将扇区划分为多个块。
缓冲区是内核用于加速磁盘操作的关键结构。当块被调入内存时,通常会放入缓冲区中。每个缓冲区与一个块对应,表示磁盘块在内存中的状态。缓冲区头(buffer_head结构体)用于描述缓冲区的详细信息,包括缓冲区的位置、大小和当前状态。
在早期内核版本中,缓冲区头是所有块I/O操作的核心容器,但存在较大的内存占用和操作复杂性问题。为了解决这些问题,内核引入了bio结构体作为块I/O的基本容器。
bio结构体代表了块I/O操作中的片段链表。每个片段描述了一个内存缓冲区在物理页中的位置。bio结构体的优势在于它能够处理分散的缓冲区,不需要保证单个缓冲区是连续的。这种灵活性极大地提高了内核对块I/O操作的控制能力。
bio结构体内部包含了bio_vec结构体数组,每个bio_vec结构体描述了一个片段的具体信息,包括所在页、页内偏移和片段长度。在块I/O操作中,bio结构体通过bio_io_vec域指向需要处理的所有片段。
I/O调度程序的主要职责是管理块设备的请求队列,将请求发送到对应的块设备进行处理。为了减少磁盘寻址时间,I/O调度程序采用合并与排序的策略。
合并操作将相邻的磁盘块请求合并为一个大块操作,减少磁盘寻址次数。排序操作则将所有请求按扇区排列顺序进行处理,使磁盘头能以直线运动处理所有请求,从而降低整体磁盘寻址时间。
为了解决I/O调度程序中可能导致的饥饿问题(例如写操作长时间占用磁盘资源,导致读操作无法及时处理),最后期限I/O调度程序为每个请求设置了超时时间。读操作的超时默认为500ms,写操作为5s。这种机制能够有效防止某些请求长时间占用磁盘资源,确保系统能够公平分配磁盘I/O资源。
预测I/O调度程序通过添加等待时间机制,优化了读操作的响应时间。提交读请求后,调度程序主动等待几毫秒,期间系统会优先处理与当前请求位置相邻的读请求。这种机制虽然可能带来轻微的性能损失,但能够显著提升读操作的响应速度,尤其是在系统负载较高时。
空操作I/O调度程序主要用于优化真正的随机访问设备(如SSD)。该调度程序执行合并操作,但不进行排序或其他复杂处理。由于随机访问设备没有寻道的负担,空操作能够有效提升系统性能,适合大多数高性能存储设备。
在实际应用中,I/O调度程序的选择往往需要根据具体工作负荷进行权衡。Linus电梯调度程序在早期版本中被广泛使用,但在2.6内核版本中被取代。最后期限I/O调度程序和预测I/O调度程序分别针对不同的性能需求提供了不同的优化方案。
空操作I/O调度程序则适用于特定的高性能存储设备需求。理解这些调度程序的工作原理和特点,有助于优化系统性能,提升整体工作效率。
转载地址:http://dddq.baihongyu.com/