Linux 中的用户/内核空间 read(2)/write(2) 是操作系统中的通用设计吗?

Is the user/kernel space copy in Linux read(2)/write(2) a general design in operating systems?

提问人:Xavier Z. 提问时间:10/26/2023 最后编辑:Xavier Z. 更新时间:10/27/2023 访问量:31

问:

我有一个关于 Linux 的 read(2)/write(2) 系统调用的多部分问题:

1.标题中描述的复制行为究竟在哪里说明?

我尝试浏览 Linux 手册页(2),但没有找到明确说明。然而,许多讨论声称手册页“清楚地说明”了这种行为。

2.在读/写(2)过程中,在内核空间中发生的复制是否真的复制了页表的条目内容?

关于操作系统的教科书提到内存管理是通过页表完成的,页表将内存映射到文件系统。页表显然是一个内核空间对象。这两个概念通常没有联系:在讨论接口时,人们会说“读/写(2)涉及内核空间的副本”,而在讨论操作系统时,人们会说“内存是使用页表来管理的”。

3.As 标题中提到的,鉴于我在操作系统教科书中没有找到这方面的明确信息,我很好奇:读/写过程中的内核空间副本是标准设计,还是 Linux 独有的?

Linux 操作系统 POSIX 系统调用 缓冲

评论


答:

1赞 user22405329 10/27/2023 #1

在“sendfile”手册中对此进行了描述。对于 和 ,复制是一个实现细节 - 程序员不必知道它。对于 ,它是基本原理的一部分 - 它解释了它与现有调用的不同之处。readwritesendfile

通常,/ 可以通过以下三种方式之一实现:readwrite

  1. 它复制到内核缓冲区并返回。实际写入稍后执行。For - 内核会提前预读,系统调用只是复制数据。readread
  2. 它会阻塞,直到操作完成,可能会持续数百万个 CPU 周期。磁盘控制器可以直接从用户空间读取/写入数据,但不能保证:缓冲区可能不符合直接内存访问的条件(大小、RAM 对齐、磁盘对齐等) - 在这种情况下,无论如何都会完成复制。
  3. 它立即返回,稍后执行操作。程序必须保持缓冲区不变,直到操作完成。出于同样的原因,它仍然可以进行复制。

手册允许选项 1 和 2,但实际上,选项 1 是最常用的,因为它通常更快。在 Windows 上,WriteFile/ReadFile 也允许选项 3,但前提是程序明确要求它。

页表不会将任何内容映射到文件系统 - 它们将当前进程和内核的虚拟地址映射到 RAM 或设备 MMIO 寄存器的物理地址。可能会触发文件缓冲区的内存分配,但除此之外,文件操作与页表无关。write

还有另一个系统调用 - 。该系统调用以这样一种方式修改页表,使内核文件缓冲区出现在进程内存中。这样,您就可以直接修改内核端缓冲区,进行正常的内存读取和写入。然后,内核可以命令磁盘控制器将它们存储在磁盘上。mmap