繁体   English   中英

为什么子进程在使用fork和pipe从父级的输出中输入stdin时正在等待?

[英]Why child process is waiting while using fork and pipes for stdin from parent's output?

我了解fork和pipe的工作原理,但是我对子进程和父进程的流程有疑问。由于我们使用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; 
}

您没有在子级中关闭足够的文件描述符。

经验法则 :如果将管道的一端dup2()为标准输入或标准输出,请尽快关闭pipe()返回的两个原始文件描述符。 特别是,在使用任何exec*()系列函数之前,应关闭它们。

如果您使用带有F_DUPFD dup()fcntl()复制描述符,则该规则也适用

在这种情况下,孩子需要在复制后关闭fds[1] 由于它仍处于打开状态,因此rev将永远不会收到EOF,因为从理论上讲,有一个可以写入输入的进程( rev子进程)。

您应该使用fclose(stream)而不是close(fds[1])因为输出已缓冲,并且fclose()知道要刷新缓冲区,但是close()没有任何线索。 但是,通过在误导的close()之前使用fflush(stream) close() ,可以避免出现问题。

这导致:

#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>

int main(void)
{
    int fds[2];
    pid_t pid;

    pipe(fds);

    pid = fork();
    if (pid == (pid_t)0)
    {
        close(fds[1]);
        dup2(fds[0], STDIN_FILENO);
        close(fds[1]);
        execlp("rev", "rev", 0);
    }
    else
    {
        FILE *stream;
        close(fds[0]);
        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");
        fclose(stream);
        waitpid(pid, NULL, 0);
    }
    return 0;
}

产生输出:

From there to here,
and here to there,
funny things are everywhere.
 - Dr. Seuss

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM