我理解fork和pipes是如何工作的,但我对父进程和子进程的流程有疑问。因为我们使用fork,所以父进程和子进程的执行顺序是未定义的,但为什么子进程要等待来自父进程的stdin。如果子进程先执行,会发生什么?它必须在控制台中打印空?但这并没有发生,我能知道为什么吗?
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main () {
int fds[2]; pid_t pid;
/* File descriptors for the two ends of the pipe are placed in fds. */
pipe (fds);
/* Fork a child process. */
pid = fork ();
if (pid == (pid_t) 0) {
/* Child proces -. Close the write end of the file descriptor. */
close (fds[1]);
/* Connect the read end of the pipe to standard input. */
dup2 (fds[0], STDIN_FILENO);
/* Replace the child process with the “rev” program. */
execlp("rev", "rev", 0); }
else {
/* This is the parent process. */
FILE* stream;
/* Close the read end of the file descriptor. */
close (fds[0]);
/* Convert the write file descriptor to a FILE object */
stream = fdopen (fds[1], "w");
fprintf (stream, ",ereh ot ereht morF\n");
fprintf (stream, ",ereht ot ereh dna\n");
fprintf (stream, ".erehwyreve era sgniht ynnuf\n");
fprintf (stream, "ssueS .rD - \n");
fflush (stream);
close (fds[1]);
/* Wait for the child process to finish. */
waitpid (pid, NULL, 0);
}
return 0;
}
1条答案
按热度按时间piok6c0g1#
您没有关闭子进程中足够的文件描述符。
经验法则:如果您将管道的一端
dup2()
到标准输入或标准输出,请尽快关闭pipe()
返回的两个原始文件描述符。特别是,在使用任何exec*()
系列函数之前,您应该关闭它们。如果使用
dup()
或fcntl()
与F_DUPFD
复制描述符,则该规则也适用在这种情况下,子进程需要在复制
fds[1]
后关闭它。因为rev
仍然是打开的,所以它永远不会接收EOF,因为理论上有一个进程(rev
子进程)可以写入输入。您应该使用
fclose(stream)
而不是close(fds[1])
,因为输出是缓冲的,fclose()
知道要刷新缓冲区,但close()
没有任何线索。但是,通过在被误导的close()
之前使用fflush(stream)
,确实可以避免问题。这导致:
其产生输出: