先了解進程概念
1,進程 :
進程是一個具有獨立功能的程序關於某個數據集合的一次運行活動。它可以申請和擁有系統資源,是一個動態的概念,是一個活動的實體。它不只是程序的代碼,還包括當前的活動,通過程序計數器的值和處理寄存器的內容來表示。[來源於 百度百科]
fork() 函數的主要作用是在父進程調用的基礎上創建一個其的子進程。子進程是一個相對的概念,他會複製父進程的數據代碼等部分,是完全複製一份而不是共用相同的變量相當於克隆。fork() 函數有一個特點就是隻調用一次卻會返回兩次,一次是父進程返回的值 一個大於0的數 (即他創建的子進程的PID,PID 是操作系統中進程的唯一標識 ),而另外一次則是子進程返回的值 爲0。還有一種情況就是父進程調用該函數的時候如果返回的 <0 的數則說明創建進程失敗(失敗的原因有很多)。另外一個值得注意的是調用 fork() 函數 的時候 子進程是接着該調用後的代碼繼續執行的,如果其後還存在調用fork() 函數 子進程也可以作爲父進程創建它的子進程。
具體過程我們來看下面的代碼:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
pid_t pid;
int i = 0;
for(i =0 ; i < 2 ; i++)
{
pid = fork();
if (pid == 0) {
printf("PID: %d\nreturned: %d\n",
getpid(), pid);
} else {
printf("PID: %d\nreturned: %d\n",
getpid(), pid);
}
}
return 0;
}
\\代碼我在 VS2017 上運行不了 找不到 unistd.h 該頭文件的意思是 unix stdio 的意思 . (沒有解決 哈哈 )所以我直接在 linux系統上編譯執行的 .
運行結果大概是這個樣子的
1,首先我通過 gcc 編譯該源文件 forkT.c 並且將其命令爲 FT , 然後執行 FT 文件 , 得到打印結果 。
2,第一個打印的 PID 4807 和 return 4808 是父進程(PID = 4807)調用 fork() 函數 創建的一個 子進程(PID = 4808)
3,第二個打印的 PID 4808 和 return 0 是子進程(PID = 4808)複製的變量 pid 被賦值爲0 , 我們前面講過fork() 函數的一個特點,就是父進程被調用一次,會返回兩次,一次是父進程的創建的子進程的pid ,另外一次則是子進程的返回值 爲 0,這裏直接賦給 子進程中的 pid 了 .
4,第三次打印的PID 4807 和 return 4809 說明了一個父進程(PID 4807)進入for循環第二次循環 i=1,此時再次調用fork() 函數並且創建另外的一個新的進程(PID = 4809).
5,第四次打印的PID 4808 和 return 4810 說明進程(PID 4807)的子進程(PID 4808)進入for循環的第二次循環 i =1,此時調用了fork() 函數 創建一個新的進程(PID 4810)。此時該進程(PID 4808)即是子進程又是父進程。
6,第五次打印的PID 4809 和 return 0 是 進程(PID 4807)的創建的另外一個子進程進程(PID 4809)執行的結果,此時該進程(PID 4809)在for循環的第二次循環裏 i=1,並且pid=0.
7 ,第六次打印的PID 4810 和 return 0 是進程(PID 4808)的子進程。
如果看的有點懵不慌我們來看下下面的圖,或許就明白了。