根据维基百科(可能是错误的)
发出fork()系统调用时,将创建与父进程对应的所有页面的副本,并由OS加载到子进程的单独内存位置。但这在某些情况下是不需要的。请考虑以下情况:孩子执行
exec
系统调用(用于从C程序中执行任何可执行文件)或在以后很快退出fork()
。当仅需要子进程来执行父进程的命令时,就不需要复制父进程的页面,因为exec
用要执行的命令替换了调用它的进程的地址空间。在这种情况下,将使用一种称为写时复制(COW)的技术。使用此技术时,发生派生时,不会为子进程复制父进程的页面。而是在子进程和父进程之间共享页面。每当进程(父级或子级)修改页面时,都会为执行修改的那个进程(父级或子级)单独制作该页面的单独副本。然后,此过程将使用新复制的页面,而不是将来所有引用中的共享页面。另一个过程(未修改共享页面的过程)继续使用页面的原始副本(现在不再共享)。此技术称为写时复制,因为在某些进程向页面写入内容时会对其进行复制。
似乎当任何一个进程试图将其写入页面时,都会分配该页面的新副本并将其分配给产生页面错误的进程。之后原始页面将被标记为可写。
我的问题是:如果fork()
在任何进程尝试写入共享页面之前多次调用gets ,会发生什么?
pmap -XX PID
或进行验证cat /proc/PID/smap
。