为什么写入时复制时没有 SIGSEGV 信号



维基百科上的"写入时复制"文章说,写入时复制通常是通过授予对页面的只读访问权限来实现的,因此当写入页面时,页面错误陷阱处理程序可以为它映射唯一的物理内存页面。所以我的问题是,为什么用户级应用程序在发生此类页面错误时没有收到 SIGSEGV 信号?毕竟,维基百科关于SIGSEGV的文章说SIGSEGV是当进程产生无效的内存引用或分段错误时发送到进程的信号。因此,在这种情况下,这是在写入时复制的情况下,为什么没有将SIGSEGV发送到该进程。

我知道这个问题已经被问到已经有一段时间了,但我想稍微扩展一下阿列克谢的答案。

写入时复制(我假设您谈论的是虚拟内存而不是文件系统)通常如下所示:

  1. 操作系统知道写入时需要复制哪些页面。(它们是进程专用的页面。这些页面在硬件中标记为只读。但是,进程的虚拟内存映射将页面标记为可读和可写。这意味着用户进程认为它对相关页面具有完全访问权限。
  2. 当用户进程尝试写入这些页面之一时,将生成页面错误,因为处理器识别出该页面是只读的(基于前面的硬件标记)。页面错误有点像段错误,但针对内核而不是用户进程。
  3. 这会触发页面错误处理程序在内核中运行,内核查看有问题的页面,并看到它是一个尚未复制的私有页面。处理程序将创建页面的副本并将副本标记为可写。
  4. 然后,处理程序将在虚拟到物理转换表中将旧页面的地址替换为新页面的地址并退出。
  5. 此时,用户进程
  6. 将重试最后一条指令,这次写入将成功,因为新页面在虚拟内存映射(用户进程的内存权限视图)和硬件(内核的内存权限视图)级别都是可写的。

每次发生分段错误时都会生成页面错误,但大多数页面错误由内核处理,并且永远不会作为段错误传递给导致它们的进程。在较低级别处理页面错误的原因有很多,包括:

  • 访问的页面被分页到磁盘,因为它很久没有使用过了。操作系统必须将其恢复到内存中,以便进程可以再次使用它。
  • 进程是首次访问新分配的页面,并且尚未分配实际的物理页面。操作系统必须分配一个页面,然后将其插入到虚拟到物理转换表中,然后才能实际使用内存。
  • 操作系统正在玩硬件页面访问权限技巧,以允许它监视对特定页面的访问。这是写入时复制中发生的情况,但它也可以有其他用途。考虑操作系统级别的虚拟化技术,如 kvm ,其中写入来宾操作系统内存中内存映射设备在内存中的位置实际上应该写入主机操作系统中的文件或显示器。

COW 的主要思想是 COW 对用户进程完全透明,就好像它完全拥有内存而没有任何共享一样。

最新更新