繁体   English   中英

等待分叉孩子向管道中写入内容,然后继续

[英]Waiting for fork children to write to the pipe before continuing

了解有关C的fork()pipe()的信息。

下面的代码创建一个管道和一个子进程。 子级发送一条消息,而父级则读取该消息。

int main () {
    int     fd[2];
    pid_t   pid;
    pipe(fd);
    pid = fork();
    if (pid == 0) {
        // Child
        close(fd[0]);
        write(fd[1], "HELLO", (strlen("HELLO")+1));
        exit(0);
    }else{
        // Parent
        close(fd[1]);
        char buffer[80];
        read(fd[0], buffer, sizeof(buffer));
        printf("Received string: %s", buffer);
    }
    return 0;
}

一切正常。 如果您对write行进行注释,则父级将报告它收到了一个带有奇怪字符的字符串,我认为这是正常现象,因为它正在读取与程序无关的内存。

但是,这带来了一个问题:父级是否有可能在子级可以写入数据之前先读取管道? 如果发生这种情况,那将是在读取奇怪的字符。

父级如何“等待”要从子级写入的数据?

将来我可能会有几个子进程,我希望父母在继续前进之前等待所有子进程完成他们的工作。

如果您在写行中添加注释,则父级将报告它收到了一个包含奇怪字符的字符串

如果子级中的write调用被跳过,则子级进程结束,管道端的子级写端将关闭。

父级检测到孩子的管道末端已关闭,这使得对read()的调用返回。 父级实际上没有读取任何内容,因此缓冲区保持未初始化状态,并且打印出“垃圾”。

请从以下read的POSIX规范中找到相关部分:

尝试从空管道或FIFO中读取时:

  • 如果没有进程打开要写入的管道,则read()应返回0表示文件结束。

[...]

  • 如果某个进程打开了用于写入的管道并且O_NONBLOCK被清除,则read()将阻塞调用线程,直到某些数据被写入或所有打开了写入的管道的所有进程关闭了管道。

为了使您的代码能够处理孩子什么都不写的情况,请测试父母对read()的调用是否确实读取了一些内容:

            ssize_t result = read(fd[0], buffer, sizeof(buffer));
            if (-1 == result) /* Also ALWAYS test for error. */
            {
              perror("read() failed");
            }
            else if (0 == result)
            {
              fprintf(stderr, "read() returned without having read anything.\n")
            }
            else
            {
              printf("Received string: '%s'", buffer);
            }

暂无
暂无

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

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