從進程開始,搜索和理解進程
Google 搜索關鍵詞: C fork example
什麼是fork
Fork系統調用用於創建一個稱爲子進程的新進程,該子進程與進行fork()調用的進程(父進程)同時運行。
創建新的子進程後,兩個進程都將在fork()系統調用之後執行下一條指令。
子進程使用與父進程相同的pc(程序計數器),相同的CPU寄存器,相同的打開文件。
fork返回值
它不帶任何參數,並返回一個整數值。以下是fork()返回的不同值。
負值:創建子進程失敗。
零:返回到新創建的子進程。
正值:返回給父級或調用者。該值包含新創建的子進程的進程ID。
寫點代碼
光看上面的解釋有點幹,來份代碼
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { // make two process which run same // program after this instruction fork(); printf("Hello world!\n"); return 0; }
輸出:
Hello world!
Hello world!
執行fork函數後,父進程和子進程都會執行下一行代碼和後面的代碼,所以會輸出兩遍
計算hello打印的次數
#include <stdio.h> #include <sys/types.h> int main() { fork(); fork(); fork(); printf("hello\n"); return 0; }
輸出
hello
hello
hello
hello
hello
hello
hello
hello
hello打印的次數等於創建的進程數。
進程總數= 2^n,其中n是fork系統調用的數目。所以這裏n = 3,2^3 = 8
還不理解?我們來逐行分析
fork (); // Line 1 fork (); // Line 2 fork (); // Line 3 L1 // There will be 1 child process / \ // created by line 1. L2 L2 // There will be 2 child processes / \ / \ // created by line 2 L3 L3 L3 L3 // There will be 4 child processes // created by line 3
因此,總共有八個進程(新的子進程和一個原始進程)。
如果我們想將流程之間的關係表示爲樹層次結構,則如下所示:
主進程:P0
第一個fork函數創建的進程:P1
第二個fork函數創建的進程:P2、P3
第三個fork函數創建的進程:P4、P5、P6、P7
預測以下程序的輸出
#include <stdio.h> #include <sys/types.h> #include <unistd.h> void forkexample() { // child process because return value zero if (fork() == 0) printf("Hello from Child!\n"); // parent process because return value non-zero. else printf("Hello from Parent!\n"); } int main() { forkexample(); return 0; }
輸出:
1. Hello from Child! Hello from Parent! (or) 2. Hello from Parent! Hello from Child!
在上面的代碼中,創建了一個子進程,fork()在該子進程中返回0,並向父進程返回正整數。
在這裏,兩個輸出都是可能的,因爲父進程和子進程正在同時運行。 因此,我們不知道操作系統是首先控制父進程還是子進程。
父進程和子進程正在運行同一程序,但這並不意味着它們是相同的。 OS爲這兩個進程分配不同的數據和狀態,並且控制這些進程的流可以有所不同。
看下面的例子:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> void forkexample() { int x = 1; if (fork() == 0) printf("Child has x = %d\n", ++x); else printf("Parent has x = %d\n", --x); } int main() { forkexample(); return 0; }
輸出:
Parent has x = 0 Child has x = 2 (or) Child has x = 2 Parent has x = 0
這裏,一個進程中的全局變量更改不會影響其他兩個進程,因爲兩個進程的數據/狀態不同。而且父級和子級同時運行,因此有兩個輸出是可能的。