c - fork 和管道 : does this C program contain a race condition?

标签 c process pipe fork parent-child

我正在学习进程间通信并遇到了下面的示例程序。

我不明白在子进程完成写入之前,如何阻止父进程尝试读取(作为程序底部的else条件的一部分)

什么(如果有的话)限制父进程在子进程写入标准输出之前尝试从标准输入读取?

int main(void)
{
    int     fd[2], nbytes;
    pid_t   childpid;
    char    string[] = "Hello, world!\n";
    char    readbuffer[80];

    pipe(fd);

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

    if(childpid == 0)
    {
            /* Child process closes up input side of pipe */
            close(fd[0]);

            /* Send "string" through the output side of pipe */
            write(fd[1], string, (strlen(string)+1));
            exit(0);
    }
    else
    {
            /* Parent process closes up output side of pipe */
            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() 调用,但在子进程将数据写入管道之前,父进程不会获取任何数据。管道(并且该写入将是原子的,因为它小于管道缓冲区的长度)。父级将挂起,等待一些数据到达管道或关闭管道的每个写入端。

请注意,如果读取后 nbytes == 0,则 printf() 的输出不确定,因为 readbuffer 未初始化。

关于c - fork 和管道 : does this C program contain a race condition?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31897477/

相关文章:

c - 使用 fcntl.h close 无法正确关闭文件

linux - 如何在 Linux 中更改每个用户的默认最大进程数

c# - 64 位应用程序启动 32 位进程

c# - process.kill() 是否终止 WaitForExit() (没有时间限制)

linux - & 和 | 有什么区别在Linux中?

c - C 中管道的两种方式进程通信

c - 如何将数据通过管道传输到在 Linux 中调用 scanf() 和 read() 的程序

c - 如何在C中检查输入字符串的长度

c - 内联函数的多重定义

与 C 中的指针和虚拟内存混淆