當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


C語言 fork()用法及代碼示例


叉係統調用用於創建一個稱為子進程的新進程,該子進程與進行fork()調用的進程(父進程)同時運行。創建新的子進程後,兩個進程將在fork()係統調用之後執行下一條指令。子進程使用與父進程相同的pc(程序計數器),相同的CPU寄存器,相同的打開文件。

它不帶任何參數,並返回一個整數值。以下是fork()返回的不同值。

負值:創建子進程失敗。
:返回到新創建的子進程。
正值:返回家長或來電者。該值包含新創建的子進程的進程ID。


creating a fork process

請注意,以上程序無法在Windows環境中編譯。

  1. 預測以下程序的輸出:
    #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!
    

  2. 計算您好打印的次數:
    #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,P7

                 P0
             /   |   \
           P1    P4   P2
          /  \          \
        P3    P6         P5
       /
     P7
    
  3. 預測以下程序的輸出:
    #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為這兩個進程分配不同的數據和狀態,並且這些進程的控製流可能不同。請參見下一個示例:

  4. 預測以下程序的輸出:
    #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()係統調用用新程序替換當前進程。

行使:

  1. 一個進程執行以下代碼:
    for (i = 0; i < n; i++) 
        fork();

    創建的子進程總數為:(GATE-CS-2008)
    (A)n
    (B)2^n-1
    (C)2^n
    (D)2 ^(n + 1)-1;

    請參閱此解決方案。

  2. 考慮以下代碼片段:
    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
    請參閱此解決方案。

  3. 預測以下程序的輸出。

    #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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。