使用管道:读入子级并写入父级,反之亦然
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()
就更清楚了。
在这个简单的程序中,子进程从管道读取数据,而父进程向管道写入数据。
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()
就更清楚了。