子进程执行顺序似乎是错误的,但有效
Child-Process execution order seems wrong, but works
为什么下面的代码会执行命令:
"cat /etc/passwd | wc -l"
而不是
"wc -l | cat /etc/passwd"?
尽管调试语句的顺序是
b
a
int main() {
pid_t pid;
int fd[2];
int stdOut = dup(1);
pid = fork();
if (pid == 0) {
pipe(fd);
pid = fork();
if (pid == 0) {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
write(stdOut, "a\n", 2);
execlp("cat", "cat", "/etc/passwd", NULL);
}
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
write(stdOut, "b\n", 2);
execlp("wc", "wc", "-l", NULL);
}
wait(NULL);
return 0;
}
pipe
、dup2
和close
的使用决定了两个进程如何连接,而不是执行顺序。第一个运行的进程可能会阻塞 read
或 write
对管道的访问,直到另一个进程分别发送或接收数据。
执行顺序不能错,因为没有指定。 parent 或 child 中的任何一个都可能要等待一些东西,调度程序不保证资源的公平分配。也许创建一个child进程需要一些时间,所以parent可能会达到
write(stdOut, "b\n", 2);
在 child 达到
之前
write(stdOut, "a\n", 2);
标记 a
和 b
的显示顺序与管道中发生的情况无关。
在它们产生的那一刻,两个过程之间没有同步。
cat
命令写入其标准输出,该标准输出被重定向到管道的 write 侧。
wc
命令从其标准输入中读取,该标准输入从管道的 read 侧重定向。
因此,在任何情况下,数据都会通过管道从 cat
传输到 wc
。
为什么下面的代码会执行命令:
"cat /etc/passwd | wc -l"
而不是
"wc -l | cat /etc/passwd"?
尽管调试语句的顺序是
b
a
int main() {
pid_t pid;
int fd[2];
int stdOut = dup(1);
pid = fork();
if (pid == 0) {
pipe(fd);
pid = fork();
if (pid == 0) {
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
close(fd[1]);
write(stdOut, "a\n", 2);
execlp("cat", "cat", "/etc/passwd", NULL);
}
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
close(fd[0]);
write(stdOut, "b\n", 2);
execlp("wc", "wc", "-l", NULL);
}
wait(NULL);
return 0;
}
pipe
、dup2
和close
的使用决定了两个进程如何连接,而不是执行顺序。第一个运行的进程可能会阻塞 read
或 write
对管道的访问,直到另一个进程分别发送或接收数据。
执行顺序不能错,因为没有指定。 parent 或 child 中的任何一个都可能要等待一些东西,调度程序不保证资源的公平分配。也许创建一个child进程需要一些时间,所以parent可能会达到
write(stdOut, "b\n", 2);
在 child 达到
之前write(stdOut, "a\n", 2);
标记 a
和 b
的显示顺序与管道中发生的情况无关。
在它们产生的那一刻,两个过程之间没有同步。
cat
命令写入其标准输出,该标准输出被重定向到管道的 write 侧。
wc
命令从其标准输入中读取,该标准输入从管道的 read 侧重定向。
因此,在任何情况下,数据都会通过管道从 cat
传输到 wc
。