2016-03-08 76 views
0

說我在子進程和父進程之間創建一個管道,子進程正常結束,子進程的管道是否會自動關閉?將退出程序自動關閉管道?

此外,如果子進程也有一個子進程,並且子進程以分段錯誤結束,它是否也會終止我的孫子進程?我的意思是從流程表中刪除它(我不需要等待它)。

編輯: 例如,對於下面的代碼,我在子進程中生成一個分段錯誤,並嘗試在父進程中等待它。運行程序後,waitpid返回-1,但是當我檢查WIFEXITED(狀態)時,看起來像子進程程序正常退出。 而且我得到了一個

殺死子進程失敗:沒有這樣的進程

錯誤試圖殺死我的孫子進程。我不知道這是否因爲分段故障自動關閉子孫進程?

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h> 


int main(void) { 

    pid_t childpid; 
    int ends[ 2 ]; 
    pipe(ends); 
    if ((childpid = fork()) == -1) { 
     perror("fork failed"); 
     exit(0); 
    } 
    if(childpid == 0) { 
     pid_t cpid; 
     if ((cpid = fork()) == -1) { 
      perror("fork failed"); 
      exit(0); 
     } 
     if (cpid == 0){ 
      while(1); 
     } 
     else{ 
      printf("cpid is : %d\n",cpid); 
      char msg[32]; 
      sprintf(msg, "%d", cpid); 
      printf("cpid con is : %s\n", msg); 
      if(write(ends[ 1 ], msg, 32) == -1) { 
       perror("Write failed"); 
       exit(0); 
      } 
      char *s = NULL; 
      *s = 15; 
      while(1); 
     } 
    } 
    else{ 
     printf("childpid is : %d\n",childpid); 
     char msg[ 32 ]; 
     int cpid; 
     if(read(ends[0], msg,32) == -1) { 
      perror("read failed"); 
      exit(0); 
     } 
     cpid = atoi(msg); 
     int status; 
     while(1) { 
      if (waitpid(childpid, &status, WNOHANG) == -1) { 
       //printf("%d\n", WIFEXITED(status)); 
       if (kill(cpid, 9) == -1) { 
        perror("Killing child process failed"); 
        exit(0); 
       } 
       /*if (kill(cpid, 9) == -1) { 
        perror("Killing child process failed"); 
        exit(0); 
       }*/ 

      } 
     } 
    } 
    return 0; 
} 
+1

對第一個是的。不是第二個。 – kaylum

+0

仔細觀察最後的while循環。你等你的孩子。第一次嘗試可能會成功。您的孩子的狀態已被收回,並且該pid不再屬於您。下一次迭代。你在一個不屬於你的pid上等待 - 等待肯定會失敗。你試圖殺死孫子 - 你成功了。下一次迭代。你的等待繼續失敗,現在殺人失敗了。你退出。 – PSkocik

+1

是的,我剛剛在幾秒鐘前弄明白了這樣一個愚蠢的錯誤。不管怎麼說,還是要謝謝你! – user5574376

回答

4

操作系統將關閉所有與已經死亡或退出的進程相關的文件描述符。如果它關閉了指向管道讀端的最後一個filedescriptor,那麼寫端寫入端將開始生成SIGPIPE(fds是對它們後面的vnode實體的引用計數引用)。

如果父母死亡,其子女將被重新分配至initinit將等待它。 (無論如何,祖父母不能在子孫後代登錄wait)。

+0

那麼init會不會殺死孫子進程?等到它終止? – user5574376

+0

@ user5574376這是正確的。該進程仍然屬於一個進程組,並且可能被殺死,因爲該進程組例如通過作業控制(^ C)發送了SIGINT,或者當進程進入休眠並且其進程組變爲孤立進程組時,發送了SIGHUP。 – PSkocik

+0

我知道當一個子進程正常結束時,我的孫子進程會被init使用,但是當子進程產生一個seg錯誤時會發生什麼。在我的子進程產生分段錯誤後,當我嘗試通過其pid殺死孫子進程時。我沒有這樣的過程錯誤。但是當我沒有生成seg故障並且只是簡單地殺掉子進程時,我可以成功地殺死孫子進程而沒有這樣的進程錯誤。 – user5574376