2015-12-21 21 views
1

我想了解以下內容,其中只有子進程正在創建子進程。fork()並在C中退出()

int main(int argc, char **argv) { 
    int i; 
    int n; 
    int num_kids; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: forkloop <numkids>\n"); 
     exit(1); 
    } 

    num_kids = atoi(argv[1]); 

    for (i = 0; i < num_kids; i++) { 
     n = fork(); 
     if (n > 0) { 
      printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i); 
      if (wait(NULL) == -1) { 
       perror("wait"); 
      } 
      exit(0); 
     } else { 
      printf("pid = %d, ppid = %d, i = %d\n", getpid(), getppid(), i); 
     } 
    } 
    return 0; 
} 

我的理解是,在每個循環結束時,父進程退出,並且子成爲新的父進程?原因是exit()語句,它終止父進程?另外,在父節點中wait(),等待它的子節點終止,循環的每次迭代,然後才退出?但是,那麼這個孩子從來沒有真正退出,那麼等待聲明什麼時候開始起作用呢?

+0

建議您運行該程序,看看會發生什麼。如果有幫助的話,添加一些'printf'語句。這是瞭解它的最好方法。但是,是的,「等待」確實等待孩子退出。由於for循環到達最後,最後創建的孩子不會調用fork。所以它會通過到達'main'的末尾而退出,然後它的父節點將退出,如此連上。 – kaylum

+0

您目前有父母等待其第一個孩子死亡,然後退出,而孩子繼續執行循環的下一次迭代(就好像它是父母一樣)。所以是的,你所描述的事情大多是正確的,除了孩子死了。主要問題是父母不會立即離開 - 所有後代(其子女的孩子的孩子等)必須死亡。您可以通過報告緊接在main()中'return 0;'之前退出的進程來提高可跟蹤性。在父代碼中打印子PID也是一件好事。 –

回答

3

我的理解是,在每個循環結束時,父 進程退出,並且子成爲新的父親?原因是 exit()語句,它會終止父進程?

是的,但該過程不會立即死亡。每個「父」調用wait()並等待子進程完成。

另外,在父節點中wait(),等待它的子節點終止, 循環的每一次迭代,然後退出?

是的。這意味着「父母」進程以相反的順序死亡。這意味着第一個過程最後死亡。

但是,那麼孩子從來沒有真正退出,所以何時等待 聲明發揮作用?

所有進程死在您的代碼中。當第一個子進程繼續執行for循環時,父進程等待(以及類似地所有其他子進程等待其子進程)。最後一個過程通過走出循環而死亡,並通過main()返回而退出。