1、fork
一个程序一调用 fork 函数,零碎就为一个新的过程筹备了前述三个段,首先,零碎让新的过程与旧的过程应用同一个代码段,因为它们的程序还是雷同的,对于数据段和堆栈段,零碎则复制一份给新的过程,这样,父过程的所有数据都能够留给子过程,然而,子过程一旦开始运行,尽管它继承了父过程的所有数据,但实际上数据却曾经离开,相互之间不再有影响了,也就是说,它们之间不再共享任何数据了。而如果两个过程要共享什么数据的话,就要应用另一套函数(shmget,shmat,shmdt 等)来操作。当初,曾经是两个过程了,对于父过程,fork 函数返回了子程序的过程号,而对于子程序,fork 函数则返回零,这样,对于程序,只有判断 fork 函数的返回值,就晓得本人是处于父过程还是子过程中。
事实上,目前大多数的 unix 零碎在实现上并没有作真正的 copy。个别的,CPU 都是以“页”为单位调配空间的,象 INTEL 的 CPU,其一页在通常状况下是 4K 字节大小,而无论是数据段还是堆栈段都是由许多“页”形成的,fork 函数复制这两个段,只是“逻辑”上的,并非“物理”上的,也就是说,理论执行 fork 时,物理空间上两个过程的数据段和堆栈段都还是共享着的,当有一个过程写了某个数据时,这时两个过程之间的数据才有了区
别,零碎就将有区别的“页”从物理上也离开。零碎在空间上的开销就能够达到最小。
2、对于 exec 系列函数
一个过程一旦调用 exec 类函数,它自身就“死亡”了,零碎把代码段替换成新的程序的代码,废除原有的数据段和堆栈段,并为新程序调配新的数据段与堆栈段,惟一留下的,就是过程号,也就是说,对系统而言,还是同一个过程,不过曾经是另一个程序了。不过 exec 类函数中有的还容许继承环境变量之类的信息,这个通过 exec 系列函数中的一部分函数的参数能够失去。
对于 fork():
1、子过程复制父过程的所有过程内存到其内存地址空间中。
父、子过程的“数据段”,“堆栈段”和“代码段”完全相同,即子过程中的每一个字节都和父过程一样。
2、子过程的当前工作目录、umask 掩码值和父过程雷同,fork()之前父过程关上的文件描述符,在子过程中同样关上,并且都指向雷同的文件表项。
3、子过程领有本人的过程 ID。
对于 exec():
1、过程调用 exec()后,将在同一块过程内存里用一个新程序来代替调用 exec()的那个过程,新程序代替以后过程映像,以后过程的“数据段”,“堆栈段”和“代码段”背新程序改写。
2、新程序会放弃调用 exec()过程的 ID 不变。
3、调用 exec()之前关上关上的形容字持续关上(如同有什么参数能够令关上的形容字在新程序中敞开)