2

编辑:问题已在评论中回答

所以,我正在研究管道。长话短说,我有两个程序:

  1. 第一个程序创建 apipe和两个forks:首先fork关闭read描述符并将一些东西写入write一个(然后关闭它),第二个fork关闭write一个,dup2read管道一侧到标准输入(结束read侧本身)和execl第二个程序,给出一个文本的大小第一个fork作为参数写入;父母关闭管道两侧和waitpids 为孩子是execld (第二个)。
  2. 第二个程序只是 read从它的标准输入(管道端)中取出东西并将write其发送到标准输出,然后关闭管道端以防万一。

在这样的设置中,一切都按我的预期工作,但是当我waitpid在第一个程序中删除(或者只是等待第一个写入而不是第二个的子程序)时,第二个程序的行为很奇怪 - 它执行到最后,通过所有IO(也就是printf之前exit被执行),然后不给我提示返回。也就是说,终端看起来就像程序在等待来自标准输入的输入。如果我在没有 的情况下执行第一个程序execl,那么一切正常,如果我只使用一个参数执行第二个程序,那么它只会等到输入被提供给标准输入(因为它应该不是管道的一部分)案子)。

据我所知,当父母终止时,孩子被“继承”并被init教育wait。但即使它不是,也就是说,即使它仍然是僵尸,那仍然会很奇怪——为什么在我明确等待之前我不能得到我的提示?

代码如下(正常工作的设置):

第一个程序

  /* headers */
  int main(void)      
  {   
      int fildes[2];
      pid_t p1, p2;
      int status;
      char mess[] = "written from execved program!\n";
      int buf = strlen(mess);
      
      if(pipe(fildes) == -1) {
          perror("pipe in main");
          exit(EXIT_FAILURE);
      }
      p1 = fork(); 
      if(p1 == -1) {
          perror("fork p1 in main");
          exit(EXIT_FAILURE);
      }
      else if (p1 == 0) {
          printf("Child 1!\n");
          close(fildes[0]);
          write(fildes[1], mess, buf);
          close(fildes[1]);
          printf("Before exit in child 1!\n");
          exit(EXIT_SUCCESS);
      }
      
      p2 = fork(); 
      if(p2 == -1) {
          perror("fork p2 in main");
          exit(EXIT_FAILURE);
      }
      else if (p2 == 0) {
          printf("Child 2!\n");
          dup2(fildes[0], 0);
          close(fildes[0]);
          close(fildes[1]);
          char s_buf[30];
          sprintf(s_buf, "%d", buf);
          execl("./pipe2slave", "pipe2slave", s_buf, (char *) 0);
          perror("execl have returned");
          exit(EXIT_FAILURE);
      }
      close(fildes[0]);
      close(fildes[1]);
  /* 
   below if I wait for, say, p1, or don't wait it all, 
   the weird behavior described in my question happens 
  */
      if(waitpid(p2, &status, 0) == -1) { 
          perror("waitpid in main");
          exit(EXIT_FAILURE);
      }   
      if(WIFEXITED(status))
          printf("pipe2slave exit status is %d\n", WEXITSTATUS(status));
      printf("End of main in pipe2!\n"); 
      exit(EXIT_SUCCESS);  
  }

第二个节目

   /* headers */ 
   int main(int argc, char **argv) 
   {
        if (argc != 2) {
            perror("pipe2slave - not enough args");
            exit(EXIT_FAILURE);
        }
        printf("program name is %s\n", argv[0]);
        int buf = atoi(argv[1]);
        printf("%d\n", buf);
        char mess_in[buf];
        read(0, mess_in, buf);
        write(1, mess_in, buf);
        fsync(1);
        close(0);
        printf("end of slave!\n");
        exit(EXIT_SUCCESS); 
    }

先感谢您!

4

0 回答 0