根据维基百科(可能是错误的)
发出fork()系统调用时,会创建与父进程对应的所有页面的副本,并由OS进行子进程加载到单独的内存位置。但在某些情况下不需要这样做。考虑一个孩子执行" exec"系统调用(用于在C程序中执行任何可执行文件)或在fork()之后很快退出。当需要子进程来执行父进程的命令时,不需要复制父进程'页面,因为exec用要执行的命令替换调用它的进程的地址空间。
在这种情况下,使用称为写时复制(COW)的技术。使用此技术,当发生fork时,不会为子进程复制父进程的页面。相反,页面在子进程和父进程之间共享。每当进程(父进程或子进程)修改页面时,就会对执行修改的进程(父进程或子进程)单独创建该特定页面的单独副本。然后,此过程将使用新复制的页面,而不是将来所有引用中的共享页面。另一个进程(未修改共享页面的进程)继续使用页面的原始副本(现在不再共享)。这种技术称为写时复制,因为当某个进程写入页面时会复制该页面。
似乎当任一进程尝试写入页面时。将分配新页面副本并将其分配给生成页面错误的进程。之后,原始页面被标记为可写。
我的问题是:如果在任何进程尝试写入共享页面之前多次调用fork会发生什么?
答案 0 :(得分:12)
如果从原始父进程多次调用fork
,则每个子进程和父进程都将其页面标记为只读。当子进程尝试写入数据时,父进程中的页面将被复制到其地址空间,并且复制的页面在子进程中被标记为可写,但不在父进程中。
如果从子进程调用fork
并且祖母尝试写入,则原始父级的页面将被复制到第一个子级,然后复制到大子级,并且所有页面都被标记为可写
答案 1 :(得分:2)
如果原始页面属于单个进程,则该页面仅标记为可写入,如果存在多个分支,则可能不是这种情况。新页面始终标记为可写,因为它只属于尝试编写它的进程。