2011-07-19 23 views
0

http://man7.org/tlpi/code/online/book/procexec/multi_wait.c.html系統如何知道有沒有更多的unwaited,基於這個孩子

int 
main(int argc, char *argv[]) 
{ 
    int numDead;  /* Number of children so far waited for */ 
    pid_t childPid; /* PID of waited for child */ 
    int j; 

    if (argc < 2 || strcmp(argv[1], "--help") == 0) 
     usageErr("%s sleep-time...\n", argv[0]); 

    setbuf(stdout, NULL);   /* Disable buffering of stdout */ 

    for (j = 1; j < argc; j++) { /* Create one child for each argument */ 
     switch (fork()) { 
     case -1: 
      errExit("fork"); 

     case 0:      /* Child sleeps for a while then exits */ 
      printf("[%s] child %d started with PID %ld, sleeping %s " 
        "seconds\n", currTime("%T"), j, (long) getpid(), 
        argv[j]); 
      sleep(getInt(argv[j], GN_NONNEG, "sleep-time")); 
      _exit(EXIT_SUCCESS); 

     default:     /* Parent just continues around loop */ 
      break; 
     } 
    } 

    numDead = 0; 
    for (;;) {      /* Parent waits for each child to exit */ 
     childPid = wait(NULL); 
     if (childPid == -1) { 
      if (errno == ECHILD) { 
       printf("No more children - bye!\n"); 
       exit(EXIT_SUCCESS); 
      } else {    /* Some other (unexpected) error */ 
       errExit("wait"); 
      } 
     } 

     numDead++; 
     printf("[%s] wait() returned child PID %ld (numDead=%d)\n", 
       currTime("%T"), (long) childPid, numDead); 
    } 
} 

上的錯誤,等待返回-1。一個可能的錯誤是呼叫 進程沒有(先前未等待的)子級,這由 errno值ECHILD表示。

$ ./multi_wait 7 1 4 
[13:41:00] child 1 started with PID 21835, sleeping 7 seconds 
[13:41:00] child 2 started with PID 21836, sleeping 1 seconds 
[13:41:00] child 3 started with PID 21837, sleeping 4 seconds 
[13:41:01] wait() returned child PID 21836 (numDead=1) 
[13:41:04] wait() returned child PID 21837 (numDead=2) 
[13:41:07] wait() returned child PID 21835 (numDead=3) 
No more children - bye! 

問題

系統如何知道有沒有更多的unwaited,兒童和返回ECHILD。 例如,在這個例子中,如果有些孩子睡了很長時間會怎麼樣?

回答

1

內核爲每個正在運行的進程維護一個數據結構。它還維護死亡但未等待的進程(殭屍)的數據結構。父進程的數據結構有關於尚未等待的子進程的信息(無論是殭屍還是還活着,殭屍的主要區別在於它們幾乎沒有肉體,即它們的數據結構只包含退出狀態,資源使用情況,而不是更多,所以他們非常loghtweight)。

+0

我可以這樣說:如果主進程開始再次等待,殭屍會變成非殭屍進程嗎? – q0987

+1

如果當前進程有一個殭屍小孩,在當前進程通過'wait *()'獲取它之後,殭屍會消失。 – ninjalj

2

該系統跟蹤每個過程。您可以使用命令ps xf來查看您的Ubuntu系統上的進程樹。

特別是,在這個列表中可以看到每個進程的狀態:R =運行,S =睡眠,T =停止,Z =殭屍(終止,等待家長來收集與wait()系統調用退出狀態)。

使用此信息,系統知道何時返回ECHILD(不再有子女離開)。

相關問題