我一直在尝试做的是建立一个分叉两个孩子的程序。父进程从 stdin 读取,然后通过管道将其重定向到其子进程。然后孩子复制管道的读取端,以便它可以从标准输入(而不是管道)读取,然后将其打印到标准输出。这是代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[100];
int pipe_one[2];
// int pipe_two[2];
pipe(pipe_one);
// pipe(pipe_two);
// First child
switch(fork()) {
case -1:
exit(EXIT_FAILURE);
case 0:
close(pipe_one[1]);
dup2(pipe_one[0], STDIN_FILENO);
close(pipe_one[0]);
while (fgets(buf, 100, stdin)) {
fputs(buf, stdout);
}
fflush(stdout);
exit(EXIT_SUCCESS);
default:
break;
}
// Second child
/* switch(fork()) {
case -1:
exit(EXIT_FAILURE);
case 0:
close(pipe_two[1]);
dup2(pipe_two[0], STDIN_FILENO);
close(pipe_two[0]);
while (fgets(buf, 100, stdin)) {
fputs(buf, stdout);
}
fflush(stdout);
exit(EXIT_SUCCESS);
default:
break;
}*/
close(pipe_one[0]);
// close(pipe_two[0]);
FILE *out_1 = fdopen(pipe_one[1], "w");
// FILE *out_2 = fdopen(pipe_two[1], "w");
while (fgets(buf, 100, stdin)) {
fputs(buf, out_1);
// fputs(buf, out_2);
}
fflush(out_1);
// fflush(out_2);
fclose(out_1);
// fclose(out_2);
close(pipe_one[1]);
// close(pipe_two[1]);
wait(NULL);
//wait(NULL);
exit(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)
我已经注释掉了与第二个孩子有关的所有部分。如果我运行这个程序,它可以完美运行(它从标准输入读取,直到遇到 EOF,然后将其打印到标准输出)。但是,如果我尝试用第二个叉子做完全相同的事情(请参阅注释掉的部分),它会做完全相同的事情,只是在打印完所有内容后程序不会终止。我一直无法找到原因。
我的猜测是我不会在两个孩子中重复 stdinfileno 两次。但是,我们的任务要求我们这样做。有什么我想念的吗?如果有人能看一下我真的很高兴!
管道的读端只有在写端的所有描述符都关闭后才到达 EOF。
您不会关闭pipe_two[0]第一个孩子,因此第二个孩子不会退出,直到第一个孩子退出。
您不会关闭pipe_one[0]第二个孩子,因此第一个孩子不会退出,直到第二个孩子退出。
顺便一提,
pipe_two[1]在第一个孩子中关闭会很好。
pipe_one[1]在第二个孩子中关闭会很好。
还,
dup2(pipe_one[0], STDIN_FILENO);
close(pipe_one[0]);
while (fgets(buf, 100, stdin)) ...;
Run Code Online (Sandbox Code Playgroud)
可以减少到
FILE *f = fdopen(pipe_one[0]);
while (fgets(buf, 100, f)) ...;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35 次 |
| 最近记录: |