关于fork()和exec()如何工作的困惑

时间:2014-08-19 07:28:19

标签: unix operating-system

请考虑以下事项:

enter image description here

我感到困惑的地方在于父母"的子步骤。如果您正在运行诸如skype之类的进程,如果它是forks,是否复制了skype,那么用其他程序覆盖该进程副本?如果子进程的内存要求与父进程有很大不同,该怎么办?不会像父母一样分配相同的地址空间吗?

我觉得我认为这一切都错了,也许是因为我想象这些过程是执行中的整个程序而不是一些简单的指令,例如"将数据从X复制到Y&# 34。

2 个答案:

答案 0 :(得分:2)

fork(2)很难理解。对此进行了解释,另请阅读fork (system call) wikipage以及Advanced Linux Programming的几个章节。请注意,fork 复制正在运行的程序(即/usr/bin/skype ELF可执行文件),但它是懒惰地复制(使用copy-on-write技术 - 通过配置MMU {} address space virtual memoryprocess}。每个进程都有自己的地址空间(但可能与其他一些进程共享一些段,请参阅mmap(2)execve(2) ....)。由于每个进程都有自己的地址空间,因此一个进程的地址空间的更改不会(通常)影响父进程。但是,流程可能有shared memory但需要同步:请参阅shm_overview(7)& sem_overview(7) ...

根据fork的定义,在fork系统调用之后,父进程和子进程具有几乎相等的状态(特别是子进程的地址空间是父母的地址空间)。唯一的区别是fork的返回值。

execve正在覆盖当前进程的地址空间和寄存器。

请注意,在Linux上,所有进程(除少数例外情况,如内核启动的进程,如/sbin/modprobe等)都是通过fork - 来自pid的初始/sbin/init进程获得的1。

最后,system calls - 列在syscalls(2)中 - 与fork类似,从应用程序的角度来看是一个基本操作,因为真正的处理是在{{1}}内完成的{3}}。与Linux kernel一起玩。另请参阅strace(1)this answer

进程通常是某些机器状态(that one)+其地址空间+某些内核状态(例如registers)等等(但请阅读file descriptors)。< / p>

花点时间关注我给你的所有链接。

答案 1 :(得分:2)

所有现代Unix实现都使用virtual memory。这允许他们在分叉时逃脱not actually copying much。相反,他们的内存映射包含指向父内存的指针,直到他们开始修改它为止。

当子进程执行程序时,该程序被复制到内存中(如果它还没有存在),并且进程的内存映射被更新为指向新程序。