使用管道:读入子级并写入父级,反之亦然

Using pipes: read in child and write in parent or vice versa

在这个简单的程序中,子进程从管道读取数据,而父进程向管道写入数据。

int main()
{
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    switch (pid)
    {
        case 0:
        {
            close(fd[1]);
            char buf[16];
            ssize_t ret = read(fd[0], buf, sizeof buf);

            printf("[%d] read() returned %ld bytes: '%s'\n", getpid(), ret, buf);
            close(fd[0]);
        }
        break;

        default:
        {
            close(fd[0]);
            ssize_t ret = write(fd[1], "text", 5);

            printf("[%d] write() returned %ld bytes\n", getpid(), ret);
            close(fd[1]);
            while(wait(NULL) > 0);
            break;
        }
    }
}

一切都按预期进行,输出如下所示:

[1738] write() returned 5 bytes
[1739] read() returned 5 bytes: 'text'

现在,当我在这里颠倒角色时,问题就开始了——让父从管道读取并让子写入:

int main()
{
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    switch(pid)
    {
        case 0:
        {
            close(fd[0]);
            ssize_t ret = write(fd[1], "text", 5);
            printf("[%d] write() returned %ld bytes\n", getpid(), ret);
            close(fd[1]);
        }
        break;
        default:
        {
            close(fd[1]);
            char buf[16];
            ssize_t ret = read(fd[0], buf, sizeof buf);

            printf("[%d] read() returned %ld bytes: '%s'\n", getpid(), ret, buf);

            close(fd[0]);
            while (wait(NULL))
                ;
        }
        break;
    }

}

输出为

[1752] read() returned 5 bytes: 'text'
[1753] write() returned 5 bytes
^C

这看起来不错,除了我必须发送 SIGINT 来终止进程(我猜是父进程)。为什么我会出现这种行为?

wait() returns -1 在发生错误时,包括当调用进程没有(更多)child 个进程等待时。它 returns 成功收集的 child 的 PID。有效的 PID 都大于 0,因此 wait() never returns 0。因此,您的 ...

            while(wait(NULL))
                ;

...永不终止。

...

            while(wait(NULL) > 0);

... 第一个代码更有意义,尽管它有点晦涩。它比需要多调用一次 wait() 。既然知道要等多少children(一个),那么拿到wait()能提供的状态码,再审问一下,再判断是否要wait()就更清楚了。