创建进程库函数fork

Unix操作系统提供了库函数fork来创建一个新的进程,本文分析一下fork调用背后发生了什么。

例如:

int pid = fork();

从fork函数返回,父进程(pid !=0)和子进程(pid=0)拥有相同的user-leverl context(包括data,text以及stack)的拷贝。fork函数的调用发生了下列一些列的操作:

1,它为新创建的子进程在process table分配了一个slot,并且为子进程分配了一个当前全局唯一的进程id。

2,内核初始化刚刚分配的子进程的process table slot,从父进程process talbe entry中复制相应的field。例如:父进程的实际用户ID和有效用户ID,父进程的进程组;父进程的nice值;此外,内核会在子进程的 process table slot的parent-process field中填写父进程的进程ID,使子进程才处在进程树结构中。内核也为子进程初始化各种CPU调度参数,例如:初始优先级别,初始CPU使用和各种 time field的值。

3,内核为子进程设置和reference file相关的一些信息。首先设置父进程的当前目录为子进程的当前目录,并且将当前目录的引用值增加1,相应的将它对应的inode的count值增加 1。接着,查找父进程的user file description table,顺着找到对应文件的global file table,将global file table的引用值增加1。因为父子进程share每个文件的file table,但是他们拥有各自的user file description table。这点类似于dup系统调用的功能,只是dup中共享filte table的user file description table在一个进程中。

4,内核开始创建子进程的user-level contex。它为子进程分配u area,region和辅助的page tables。复制每个region从它的父进程相应的region(和实现有关,可能父子进程共享某个region),并且将这些region依附到子 进程空间。u area有一个field指向自己的process table slot,除了这个field外,其他的和父进程一样。

5,内核开始创建子进程的kernel-level context。内核首先复制父进程的context layer 1(包括用户保存的寄存器的值和fork系统调用的stack frame)到子进程的进程空间。

6,当context创建好以后,父进程完成fork函数,将子进程的状态变为“ready to run”,并且返回子进程的进程ID。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章