【问题标题】:how to wait an exec finishes to write in pipe in C如何等待 exec 完成在 C 中的管道中写入
【发布时间】:2016-12-13 15:20:05
【问题描述】:

我想知道如何等待我的 exec 完成写入 fd 后再使用它? 问题是并非我的所有 exec 都写在管道中。 所以当我得到答案时,并不是所有的 exec 都写好了。

这里是相关代码的一部分:

   switch(fork()){
        case -1:
            perror("fork");

        case 0:
            // redirection de l'entré standard
            close(fd[0]);
            dup2(fd[1], 1);
            dup2(fd[1], 2);
            close(fd[1]);
            // éxécution de la commande courrante.
            execvp(d->command[0], d->command);
            perror("execvp");

        default:
          // gère les processus zombies.
          if(wait(NULL) == -1){
                perror("wait");
          }
          char buffer[550000] = {0};
          unlink(d->pipe1);
          unlink(d->tube2);
          unlink(tube2);
          //création du tube nommé pour le client.
          if(mkfifo(tube2, 0644) != 0)
          {
              perror("mkfifo");
              fprintf(stderr, "Impossible de créer le tube nommé.\n");
              exit(EXIT_FAILURE);
          }
          // ouverture de ce même tube
          if((d->entree_tube = open(tube2, O_WRONLY)) == -1)
          {
              perror("open");
              fprintf(stderr, "Impossible d'ouvrir l'entrée du tube nommé.\n");
              exit(EXIT_FAILURE);
          }
          close(fd[1]);
          // lecture du résultat de la commande stocké dans fd[0]
          while (read(fd[0], buffer, sizeof(buffer)) != 0)
          {
              //écriture du résultat dans l'entré du tube.
             if(write(d->entree_tube, buffer, strlen(buffer)) == -1){
                perror("write");
             }
             //réinitialisation du buffer stockant une partie du résultat de la commande.
             memset (buffer, 0, sizeof(buffer));
          }
          // on regarde si il y a eu le mot clé "fin" pour alerter la client que la commande est terminé
          // et on redonne la main à un autre client tentant de se connecter au démon.

   }

感谢您的帮助。

【问题讨论】:

  • 父进程可以wait()waitpid() 让子进程写入管道,但如果是父进程负责从管道读取,那么您应该避免这种情况,而是等待只有在孩子关闭它的管道末端之后(如果它之前没有这样做,它将在它终止时这样做)。否则,您可能会因为管道缓冲区满载而陷入僵局,而没有人准备将其排空。
  • 那我该如何避免呢?我可以不等吗?
  • 无论如何,在读者开始阅读之前,您不需要等待作者完成写作。相反,您应该使用读取循环——正如你所做的那样——并继续阅读,直到收到所有预期的数据,否则会遇到 EOF 或错误。您确实希望最终等待,但不是在您对孩子有任何其他责任的时候。
  • 我没有立即看到问题的根源。如果您编辑您的问题以提供一个捕捉您的情况的minimal reproducible example,您更有可能得到一个有用的答案。很可能问题的本质不是你想的那样。
  • 确实,我不知道如何正确地问^^,但我尽量不按你的要求等待,但它没有解决任何问题,我不明白我该怎么做通过另一个读取循环再次读取数据。

标签: c pipe exec


【解决方案1】:

我试着不按你的要求等待,但它没有解决任何问题,而且我不知道如何通过另一个读取循环再次读取数据。

您不需要另一个读取循环 - 您已经拥有的读取循环就可以了。您只需将 wait() 调用移到该读取循环后面。这就是约翰·博林格 (John Bollinger) 写道的意思:你确实希望最终等待,但不是在你对孩子有任何其他责任的时候。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多