// This code is pasted from
// http://linux.die.net/man/2/pipe
#include <sys/wait.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int pipefd[2];
pid_t cpid;
char buf;
if (argc != 2) {
fprintf(stderr, "Usage: %s <string>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { /* Child reads from pipe */ <----- Point A
close(pipefd[1]); /* Close unused write end */
while (read(pipefd[0], &buf, 1) > 0)
write(STDOUT_FILENO, &buf, 1);
write(STDOUT_FILENO, "\n", 1);
close(pipefd[0]);
_exit(EXIT_SUCCESS);
} else { /* Parent writes argv[1] to pipe */ <----- Point B
close(pipefd[0]); /* Close unused read end */
write(pipefd[1], argv[1], strlen(argv[1]));
close(pipefd[1]); /* Reader will see EOF */
wait(NULL); /* Wait for child */
exit(EXIT_SUCCESS);
}
}
据我了解,
if (...)
............; ---+
else |---> " Only ONE of them can be reached! "
............; ---+
那么,子进程如何从管道中读取 AND 父进程在此代码中写入管道?
答案 0 :(得分:3)
fork()
的结果是一个过程变为两个(通过无性繁殖)。因此,虽然if / else块的一个分支仍然在一个进程中被占用,但是有两个进程,每个进程都会占用一个路径。
更具体地说,查看fork()
返回的内容:父级的PID,新子级的0。除此之外,这两个过程几乎完全相同。因此if (cpid == 0)
检查是fork()
之后的常见模式,因此您可以在每个过程中继续使用不同的逻辑。在你的情况下,这是在一个过程中阅读和在另一个过程中写作。
答案 1 :(得分:1)
系统调用fork()
返回两次。父进程和子进程都有。您拨打fork()
的那一刻,您的程序的两个完全副本正在运行。 SINGLE差异是fork()
的返回值。
因此,当您单独考虑每个流程时,您的“if else only one”规则仍然有效。
答案 2 :(得分:1)
检查此资源以获取fork call返回值的说明:
成功时,将返回子进程的PID 父项,并在子项中返回0。失败时,返回-1 在父级中,不创建子进程,并设置errno 适当。
因此包含cpid = fork();
的行由fork之后的两个进程执行,其中父进程接收新进程'PID,子进程接收0作为PID。因此,父母和孩子之间的区别。