将输出从长时间运行的子进程重定向到父进程

时间:2012-08-28 11:58:51

标签: c unix

我有两个可执行文件 - 父进程和它的子进程,以长模式运行(例如服务器等)。我需要的是将child的stdout和stderr重定向到父进程并将它们写入文件或打印到tty,现在无关紧要。

如果我们谈论简单的孩子,这是非常简单的任务,但是对于长时间运行的孩子而言,部分输出是一个问题。

例如,让我们看看使用pipe的流行解决方案(错误检查和其他非重要部分省略):

parent.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, const char *argv[])
{
  int link[2];
  pid_t pid;
  char str[4096];

  pipe(link);
  pid = fork();

  if (pid == 0) {
    dup2(link[1], STDOUT_FILENO);
    close(link[0]);
    execl("/path_to_bin/fast_child", "fast_child", (char *)0);
  }
  else 
  {
    close(link[1]);
    read(link[0], str, sizeof(str));
    printf("Pipe contents: %s\n", str);
    wait(NULL);
  }

  return 0;
}

fast_child.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
  printf("I'm fast child\n");
  return 0;
}

以优秀且无问题的方式使用这种类型的子进程在父级中获取str(out | err),但是将此代码用作子级会导致输出问题在父级中消失:

slow_child.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, const char *argv[])
{
  for (;;)
  {
    printf("I'm slow child\n");
    sleep(1);
  }
  return 0;
}

我正在考虑将套接字使用作为解决问题的解决方案,但我确信这不是那么有效的方式,并且Unix提供了更好的工具来执行此操作(像往常一样)

谢谢。

1 个答案:

答案 0 :(得分:3)

您需要不时地从孩子那里刷新输出,否则父任务将看不到任何内容。在适当的时候使用fflush(stdout)。或者您可以关闭stdout上的缓冲,但这可能会对您的孩子产生性能影响,因为它会对每个写入的字符进行系统调用。