【问题标题】:Redirecting output from long-running child to parent process将长期运行的子进程的输出重定向到父进程
【发布时间】:2012-08-28 11:58:51
【问题描述】:

我有两个可执行文件 - 父进程和它的子进程,以长模式运行(例如服务器等)。我所需要的只是将孩子的 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 提供了更好的工具来做到这一点(像往常一样:)

谢谢。

【问题讨论】:

  • 您到底有什么问题?您不知道何时会收到孩子的输入(可以通过例如select 解决)?您不希望父母在调用wait 时被阻止(可以通过waitpidwait4 使用WNOHANG 标志来解决)?还有什么?
  • 好的,我想在一个孩子的整个(长期)生命中变得粗壮,同时这个粗壮出现,现在我根本无法得到它。换句话说,当前parent.c 实现中没有长期运行的子输出。

标签: c unix


【解决方案1】:

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

【讨论】:

  • 我无法想象fflush() 有管道。有可能吗?
  • 是的。它只是一个文件句柄。它会导致 C 运行时系统将其缓冲的内容刷新到底层句柄。
  • 所以问题出在没脸红的孩子身上。十分感谢! Additional info
猜你喜欢
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 2014-07-05
  • 1970-01-01
相关资源
最近更新 更多