fork()中的copy-on-write如何处理多个fork?

根据维基百科(这可能是错误的)

当发出fork()系统调用时,会创build与父进程对应的所有页面的副本,并由subprocess的OS将其加载到单独的内存位置。 但是这在某些情况下是不需要的。 考虑一下当一个孩子执行一个“exec”系统调用(用于执行C程序中的任何可执行文件)或在fork()之后很快退出的情况。 当需要subprocess来执行父进程的命令时,不需要复制父进程的页面,因为exec用要执行的命令replace调用它的进程的地址空间。

在这种情况下,使用了写入时复制(COW)技术。 使用这种技术,当发生分支时,父进程的页面不会被复制到subprocess。 相反,页面在subprocess和父进程之间共享。 每当一个进程(父或子)修改一个页面时,该特定页面的一个单独的副本就是针对执行修改的那个进程(父或子)进行的。 这个过程将使用新复制的页面,而不是在将来的所有引用中共享的页面。 另一个进程(没有修改共享页面的进程)继续使用页面的原始副本(现在不再共享)。 这种技术称为写时复制(copy-on-write),因为当某个进程写入时,页面被复制。

看来,当任何一个进程试图写入页面。 页面的新副本被分配并分配给产生页面错误的进程。 之后原始页面被标记为可写。

我的问题是:如果在任何进程尝试写入共享页之前多次调用fork,会发生什么?

如果fork从原始父进程中被多次调用,那么每个子进程和父进程都将其页面标记为只读。 当子进程尝试写入数据时,父进程中的页面将被复制到其地址空间,并且复制的页面在子进程中被标记为可写,但不在父进程中。

如果从子进程调用fork并且正在尝试写入,则将原始父进程的页面复制到第一个子进程,然后复制到宏进程,并将所有进程标记为可写。

如果原始页面属于单个进程,则其只能标记为可写,如果有多个分支,则可能不是这种情况。 新页面始终标记为可写,因为它只属于试图写入它的进程。