Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c-execl`d程序不';Don’别把诺言还给我_C_Pipe_Posix_Waitpid_Execl - Fatal编程技术网

c-execl`d程序不';Don’别把诺言还给我

c-execl`d程序不';Don’别把诺言还给我,c,pipe,posix,waitpid,execl,C,Pipe,Posix,Waitpid,Execl,编辑:在评论中回答问题 所以,我在研究管道。长话短说,我有两个计划: 第一个程序创建一个pipe和两个forks:第一个fork关闭read描述符,并将一些内容写入write一个(然后关闭),第二个fork关闭write一个,dup2位于管道的读侧,进入标准输入(end关闭readside本身)和execlsecond程序,给出第一个fork写入的文本大小作为参数;父级关闭管道两侧,并为execld(第二个)的子级关闭waitpids 第二个程序只需从其标准输入(管道侧)读取内容,然后将其写入标

编辑:在评论中回答问题

所以,我在研究管道。长话短说,我有两个计划:

  • 第一个程序创建一个
    pipe
    和两个
    fork
    s:第一个
    fork
    关闭
    read
    描述符,并将一些内容写入
    write
    一个(然后关闭),第二个
    fork
    关闭
    write
    一个,
    dup2
    位于管道的
    侧,进入标准输入(end关闭
    read
    side本身)和
    execl
    second程序,给出第一个
    fork
    写入的文本大小作为参数;父级关闭管道两侧,并为
    execl
    d(第二个)的子级关闭
    waitpid
    s
  • 第二个程序只需从其标准输入(管道侧)读取内容,然后将其写入标准输出,然后关闭管道侧以防万一
  • 在这样的设置中,一切都按照我的预期工作,但是当我在第一个程序中删除
    waitpid
    时(或者只是等待第一个孩子而不是第二个孩子),第二个孩子的行为很奇怪-它执行到最后,通过所有IO(即
    exit
    执行之前的
    printf
    ),然后不返回提示。也就是说,终端看起来像是程序在等待标准输入的输入。如果我执行第一个程序时没有
    execl
    ,那么一切正常,如果我只执行第二个程序并带有一个参数,那么它只会等到输入提供给标准输入(在这种情况下,它不是管道的一部分,因此应如此)

    正如我所知,当父对象终止时,子对象由
    init
    “继承”并获得
    wait
    ed。但即使它不是,也就是说,即使它仍然是一个僵尸,那么它仍然会很奇怪-为什么我在明确等待之前无法获得提示?

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

    第一个节目

      /* 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); 
        }
    
    第二个节目

      /* 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); 
        }
    

    提前谢谢你!

    你的代码对我来说很好,无论有没有
    waitpid
    ,终端都不会挂起。你是如何编译和运行这些程序的?还有,你使用的是哪个shell?@MarcoBonelli谢谢你的提示!奇怪的是,我的系统可能出了问题(Manjaro)然后。我用
    gcc
    clang
    编译,两者都没有任何特殊标志。Shell的
    bash
    。我可以问一下你的设置吗?你的代码没有等待就失败了,正如你描述的那样,但我很难确定原因。我还没有识别代码中的缺陷。这是一种竞争条件。不是太令人惊讶了,它在不同的机器上或用不同的外壳或其他什么东西表现出不同。事实上,底线是,如果你用叉子叉一个孩子,那么不等待它几乎总是一个错误。@Antontretryakov没有,但那只是运气。你的代码对我来说很好,有没有
    waitpid
    ,终端d一点也不挂。你是如何编译和运行这些程序的?还有,你使用的是哪个shell?@MarcoBonelli谢谢你的回答!奇怪,可能是我的系统出了问题(Manjaro)然后。我用
    gcc
    clang
    编译,两者都没有任何特殊标志。Shell的
    bash
    。我可以问一下你的设置吗?你的代码没有等待就失败了,正如你描述的那样,但我很难确定原因。我还没有识别代码中的缺陷。这是一种竞争条件。不是太令人惊讶了,它在不同的机器上或用不同的外壳或其他东西表现得不同。事实上,底线是,如果你用叉子叉一个孩子,那么不等待它几乎总是一个错误。@AntonTretyakov没有,但那只是运气。