2011-11-17 93 views
4

被這些系統調用練習,但我stucked這個代碼:理解叉(),睡眠()和流程通量

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

main() 
{ 
    pid_t pid; 
    switch(pid = fork()) 
    { 
     case -1: 
      printf("fork failed"); 
      break; 
     case 0: //first child 
      printf("\ni'm the first child, my pid is %d", getpid()); 
      fflush(stdout); 
      break; 
     default: //parent 
      sleep(5); /** sleep is generating problems **/ 
      printf("\ni'm the parent process, my pid is %d", getpid()); 
      printf("\ngenerating a new child"); 
      fflush(stdout); 
      switch(pid = fork()) 
      { 
       case -1: 
        printf("fork failed"); 
        break; 
       case 0: //second child 
        printf("\nhere i am, the second child, my pid is %d", getpid()); 
        break; 
       default: //parent 
        wait((int *)0); 
        printf("\nback to parent, my pid is %d", getpid()); 
      } 
    } 

    return 0; 
} 

我得到的輸出是:

i'm the first child, my pid is 6203 
i'm the parent process, my pid is 6202 
generating a new child 
back to parent, my pid is 6202 
Process returned 0 (0x0) execution time: 5.004 s 
Press ENTER to continue 

here i am, the second child, my pid is 6204

我正在嘗試的是通過sleep()來管理這些時間的簡單打印。 我不明白爲什麼程序在打印第二個子消息之前返回。 默認情況下(第二個分叉後面的那個)在其子(第二個)作用於輸出之前打印,就像他忽略了wait()一樣。因此,它的孩子在過程返回後被打印出來。

我無法弄清楚是什麼問題。我已經標記了sleep()函數,因爲如果我用wait((int *)0);替換它,那麼flux的工作方式是如何設計的(無論如何,沒有任何時間)。 在這一點上,我不再確定過程流量或sleep()使用情況(手冊頁沒有那麼有用,說實話太簡潔)。

回答

4

其實,你的電話等待工作。它檢測到第一個子進程的結束並在之後繼續。如果連續兩次調用wait(),您將獲得正確的行爲。

更新的測試代碼:

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

main() 
{ 
    pid_t pid; 
    int status; 
    switch(pid = fork()) 
    { 
     case -1: 
      printf("fork failed"); 
      break; 
     case 0: //first child 
      printf("\ni'm the first child, my pid is %d", getpid()); 
      fflush(stdout); 
      break; 
     default: //parent 
      sleep(5); /** sleep is generating problems **/ 
      printf("\ni'm the parent process, my pid is %d", getpid()); 
      printf("\ngenerating a new child"); 
      fflush(stdout); 
      switch(pid = fork()) 
      { 
       case -1: 
        printf("fork failed"); 
        break; 
       case 0: //second child 
        printf("\nhere i am, the second child, my pid is %d", getpid()); 
        break; 
       default: //parent 
        pid = wait(&status); 
        printf("\nParent detects process %d was done", pid); 
        pid = wait(&status); 
        printf("\nParent detects process %d was done", pid); 
        printf("\nback to parent, my pid is %d", getpid()); 
      } 
    } 

    return 0; 
} 

輸出:

i'm the first child, my pid is 30897 
i'm the parent process, my pid is 30896 
generating a new child 

here i am, the second child, my pid is 30940 
Parent detects process 30897 was done 
Parent detects process 30940 was done 
back to parent, my pid is 30896 
+0

非常感謝您的回答 – init6eb

+0

歡迎你,祝你學習的休息; - ) – BenC

1

的等待手冊頁說以下內容:

的wait()的函數應當暫停調用線程的執行,直到狀態信息調用進程的終止子進程的一個可用,或者直到傳遞一個信號,其作用是執行信號捕獲功能或終止該過程。如果等待同一進程終止的wait()或waitpid()中掛起多個線程,則在目標進程終止時,恰好有一個線程應返回進程狀態。

因爲第一個孩子而等待回來。