c - 在 C 中,当没有任何内容可读时,读取函数 "know"是如何实现的?

标签 c pipe fork parent-child

在下面的程序中(这不是我的,而是我修改过的),子进程对管道进行了两次写入。当我运行该程序时,我得到以下输出:

Received string: Hello, world!
This is the child process.

父进程执行的 read 如何从管道缓冲区中捕获这两个字符串?是什么(如果有的话)阻止父进程在读取第一个字符串(或第一个字符串的第一个字符)后假设没有其他内容可从缓冲区读取并退出?

有问题的程序:

int main(void)
{
    int     fd[2], nbytes;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    string2[] = "This is the child process.\n";
    char    readbuffer[80];

    pipe(fd);

    if((childpid = fork()) == -1)
    {
            perror("fork");
            return 1;
    }

    if(childpid == 0)
    {
            /* Child process closes pipe's input file descriptor */
            close(fd[0]);

            /* Send "string" through the output side of pipe */
            write(fd[1], string, (strlen(string)));
            write(fd[1], string2, (strlen(string2)+1));
            return 1;
    }
    else
    {
            /* Parent process closes pipe's output file descriptor */
            close(fd[1]);

            /* Read in a string from the pipe */
            nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
            printf("Received string: %s", readbuffer);
    }

    return 0;
}

最佳答案

这里的关键是read()缓冲区大小80

通常 read() block 调用它的进程(设置为休眠状态)直到某些条件不发生,例如:

  • 请求的缓冲区已满
  • 数据少于请求的数据(EOF)或发生错误
  • 一个信号唤醒进程(如 ^C),这可能是您的情况,子进程退出并且系统发送一个损坏的管道 向父进程发出信号(进程唤醒并 read() 获取整个缓冲区)

请注意,这些条件取决于您正在读取的子系统,在您的情况下是 pipe。可能具有不同属性的子系统,例如缓冲区大小。一个荒谬的例子:如果内核端的管道缓冲区大小小于或等于您的第一次写入,读取进程会提前唤醒并返回截断的缓冲区。 p>

关于c - 在 C 中,当没有任何内容可读时,读取函数 "know"是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31899152/

相关文章:

c - typedef 可能未声明或不明确

linux - 终端中命令输出的说明

c - 使用 execlp() 运行 C 程序?

c - forked() 子进程上的 strcmp() 处出现 SIGSEGV 段错误

c - 打印给定的输入字符数

c++ - 使用 BST 的优先级队列——DeleteLargest 不起作用

C - 程序给出带有 for 循环的 SEGFAULT,但并非没有

c - 使用 execvp 执行 grep,从管道读取

Python - 将管道命令 fork 到后台并将其留在那里

unix - 当第一个子进程退出,然后父进程退出而不调用 wait 时会发生什么?