叉係統調用用於創建一個稱為子進程的新進程,該子進程與進行fork()調用的進程(父進程)同時運行。創建新的子進程後,兩個進程將在fork()係統調用之後執行下一條指令。子進程使用與父進程相同的pc(程序計數器),相同的CPU寄存器,相同的打開文件。
它不帶任何參數,並返回一個整數值。以下是fork()返回的不同值。
負值:創建子進程失敗。
零:返回到新創建的子進程。
正值:返回家長或來電者。該值包含新創建的子進程的進程ID。
請注意,以上程序無法在Windows環境中編譯。
- 預測以下程序的輸出:。
#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!
- 計算您好打印的次數:
#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”的打印次數等於創建的進程數。進程總數= 2n,其中n是fork係統調用的數量。所以這裏n = 3,23= 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
第二叉創建的進程:P2,P3
第三叉創建的進程:P4,P5,P6,P7P0 / | \ P1 P4 P2 / \ \ P3 P6 P5 / 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
這裏,一個進程中的全局變量更改不會影響其他兩個進程,因為兩個進程的數據/狀態不同。而且父級和子級同時運行,因此有兩個輸出是可能的。
fork() vs exec()
fork係統調用將創建一個新進程。 fork()創建的新流程是當前流程的副本,但返回的值除外。 exec()係統調用用新程序替換當前進程。
行使:
- 一個進程執行以下代碼:
for (i = 0; i < n; i++) fork();
創建的子進程總數為:(GATE-CS-2008)
(A)n
(B)2^n-1
(C)2^n
(D)2 ^(n + 1)-1;請參閱此解決方案。
- 考慮以下代碼片段:
if (fork() == 0) { a = a + 5; printf("%d, %d\n", a, &a); } else { a = a -5; printf("%d, %d\n", a, &a); }
令u,v為父進程打印的值,x,y為子進程打印的值。以下哪一項是TRUE? (GATE-CS-2005)
(A)u = x + 10和v = y
(B)u = x + 10和v!= y
(C)u + 10 = x和v = y
(D)u + 10 = x和v!= y
請參閱此解決方案。 -
預測以下程序的輸出。
#include <stdio.h> #include <unistd.h> int main() { fork(); fork() && fork() || fork(); fork(); printf("forked\n"); return 0; }
看到這個解決方案
相關文章:
演示fork()和pipe()的C程序
C語言中的僵屍和孤立進程
fork()和使用它創建的內存共享黑白進程。
參考文獻:
http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html
注:本文由純淨天空篩選整理自 fork() in C。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。