2016-03-08 42 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