【问题标题】:Closing at the right time and waiting process in C在正确的时间关闭并在 C 中等待过程
【发布时间】:2020-07-04 12:13:16
【问题描述】:

我有一个创建两个子进程的函数。在第一个子进程中,我正在写入一个文件,而在第二个子进程中,我也在一个与第一个不同的文件中写入。 在爸爸进程中,我正在执行函数execvp

我需要的是函数execvpstdoutstderr,这样两个子进程就可以将stderrstdout输出的内容写入文件。然后最后我合并这两个文件。

我想知道我应该在哪里关闭管道以及我应该在哪里使用等待,这样我在使用函数 readwrite 时不会遇到问题,这样我就不会陷入无限循环。我没有实现创建文件的函数、合并文件的函数和运行shell指令的函数,因为我只是想知道这是否是函数createTwoChild.的最佳结构@

【问题讨论】:

  • 你需要类似的东西,例如popen() 如果您想读取孩子的输出。
  • @reichhart 谢谢,但我不是想从孩子那里读取输出。孩子只是在写文件。你觉得整体结构好吗?我不确定如何关闭管道
  • 不清楚是否只是想将孩子的输出合并到父亲的输出中。注册。 “时间”:SIGCHLD 缺少 sighandler。 (不幸的是,编辑我的评论时发生了编辑超时。)
  • @reichhart 谢谢。两个孩子正在创建两个文件,他们在这个文件中写入。然后我合并这两个文件。
  • @reichart 嗯,你是对的,我应该放两个 wait(NULL) 对吗?

标签: c process pipe


【解决方案1】:

由于与 cmets 对齐,我在这里提供了一个骨架(仅针对标准输出进行了简化):

if (pipe(fd)<0) goto my_sys_error; // just an example to get out of here
if ((pid_child=fork())<0) {
  close(fd[0]); close(fd[1]);
  goto my_sys_error; // you can also use something like e.g. "return -1" to handle the error
}

if (!pid_child) {
  // the child process with exec() of which we want to get the output
  close(fd[0]); close(0);
  dup2(fd[1],1); close(fd[1]); 
  execXX(...); // some of exec() family also spawn a shell here
  close(1);
  _exit(127); // This must not happen
}

// master/parent
close(fd[1]); // master doesn't need, only child writes to it
i = read(fd[0],p,PIPEBUF_SIZE);
if (i>0) { 
  // usual handling, write to file, do whatever you like
  // should be while() instead of if(), just simplified
} else {
  // handle it, e.g. print "no data from extcmd"
}   
close(fd[0]); // close the last fd
waitpid(pid_child, &status_child, 0); 
if (!WIFEXITED(status_child)) {
  kill(pid_child,SIGKILL);
}

一些注意事项:

  • 这实际上是popen() 的简化实现。
  • 当孩子退出时,您将在读取时收到 EOF - 以这种简单的方式,不需要 SIGCHLD 的 sighandler。
  • 未涵盖其他信号处理。
  • stderr 可以简单地添加一个额外的管道。

【讨论】:

  • 谢谢!在这里,您是在主进程中执行shell指令而不是在子进程中吗?
  • 这只是一个 sn-p 并显示了一个基本的解决方案。我不知道你的“shell”从哪里来。但是主人/父母正在处理来自被执行的孩子的输出。如果主人需要做额外的事情并且不能被其执行的孩子阻止,你甚至可以通过分叉另一个孩子来异步读取数据来做更多的巫术。或者为异步处理创建一个线程(例如clone())。 (添加了关于 sys_error 的 cmets。)
  • “已接受”看起来您没有任何问题,是吗?顺便说一句 - 如果您能够支持接受的解决方案,那么也请这样做。
猜你喜欢
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多