創建進程庫函數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。

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