parent 和 child 通过 stdout 和 stdin 之间的通信
Communication between parent and child though stdout and stdin
我对 C 中的管道和分叉比较陌生,
我有一个 parent 和一个 child 进程并尝试在它们之间进行通信。
我创建了一个管道,这样:parent 的标准输出将连接到 child 的标准输入,child 的标准输出将连接到 parent 的标准输入。
我通过尝试让 parent 通过它的标准输出发送 "A" 然后 child 将从它的标准输入接收 "A" 来测试这个,之后它应该发送将 "B" 从它的标准输出返回到 parent 的标准输入。
这是我的代码,
bool pget_input(void){
char buffer[80];
fprintf(stdout,"A");
fprintf(stderr,"Parent sent out 'A' to child \n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"Parent failed to recieve from child\n");
return false;
}
fprintf(stderr,"Parent receiving from child\n");
if(strcmp(buffer, "B")==0){
fprintf(stderr,"Parent success recieve child's reply");
}
continue;
}while(true);
}
int main(int argc, char** argv){
pid_t pid = fork();
int pipe1[2];
int pipe2[2];
if (pipe(pipe1)==-1 || pipe(pipe2)==-1){
fprintf(stderr,"pipe failed\n");
exit(1);
}
if(pid > 0){
//parent
close(STDIN_FILENO); //close stdin
dup(pipe1[0]); //replace stdin with pipe1 read
close(STDOUT_FILENO); //close stdout
dup(pipe2[1]); //replace stdout with pipe2 write
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
pget_input();
wait(0);
}else if(pid ==0){
//child
close(STDOUT_FILENO); //close stdout
dup(pipe1[1]); //replace stdout with pipe1 write
close(STDIN_FILENO); //close stdin
dup(pipe2[0]); //replace stdin with pipe2 read
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execl("./child", "not matter", NULL);
perror("execvp failed");
exit(1);
}else{
fprintf(stderr,"fork failed\n");
exit(1);
}
fprintf(stderr,"Exiting\n");
exit(1);
}
哪里./child:
bool cget_input(void){
char buffer[80], command[80];
fprintf(stderr,"Child trying receive from parent\n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"child failed to receive from parent\n");
return false;
}
sscanf(buffer, "%s", command);
if(strcmp(buffer, "A") == 0){
fprintf(stderr,"Child received 'A' from Parent and sending out 'B'\n");
fprintf(stdout, "B");
}
continue;
}while(true);
}
int main ()
{
if(!cget_input()){
return 0;
}
return 1;
}
结果,parent 和 child 的标准输入都没有收到任何东西,
没通过
if (!fgets(buffer, 20, stdin))
谁能指出我的代码哪里出了问题?
谢谢,
您必须在分叉前设置管道。
以下是需要完成的顺序的概述:
- 使用 pipe() 创建管道
- 分叉
- Parent 和 child 各自关闭管道的正确末端。
- 如果需要,parent 和 child 可以使用 dup() 和 close() 重定向标准输出、标准输入
- 此时,您可以在 child 进程中 exec() 一个新程序,它不需要知道已经发生的重定向。
fork 后,parent 和child 是两个不同的进程,此时parent 无权修改child 的文件描述符。任何共享文件描述符都必须在派生之前设置。
我对 C 中的管道和分叉比较陌生,
我有一个 parent 和一个 child 进程并尝试在它们之间进行通信。
我创建了一个管道,这样:parent 的标准输出将连接到 child 的标准输入,child 的标准输出将连接到 parent 的标准输入。
我通过尝试让 parent 通过它的标准输出发送 "A" 然后 child 将从它的标准输入接收 "A" 来测试这个,之后它应该发送将 "B" 从它的标准输出返回到 parent 的标准输入。
这是我的代码,
bool pget_input(void){
char buffer[80];
fprintf(stdout,"A");
fprintf(stderr,"Parent sent out 'A' to child \n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"Parent failed to recieve from child\n");
return false;
}
fprintf(stderr,"Parent receiving from child\n");
if(strcmp(buffer, "B")==0){
fprintf(stderr,"Parent success recieve child's reply");
}
continue;
}while(true);
}
int main(int argc, char** argv){
pid_t pid = fork();
int pipe1[2];
int pipe2[2];
if (pipe(pipe1)==-1 || pipe(pipe2)==-1){
fprintf(stderr,"pipe failed\n");
exit(1);
}
if(pid > 0){
//parent
close(STDIN_FILENO); //close stdin
dup(pipe1[0]); //replace stdin with pipe1 read
close(STDOUT_FILENO); //close stdout
dup(pipe2[1]); //replace stdout with pipe2 write
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
pget_input();
wait(0);
}else if(pid ==0){
//child
close(STDOUT_FILENO); //close stdout
dup(pipe1[1]); //replace stdout with pipe1 write
close(STDIN_FILENO); //close stdin
dup(pipe2[0]); //replace stdin with pipe2 read
//close pipe1 and pipe2 read write
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
execl("./child", "not matter", NULL);
perror("execvp failed");
exit(1);
}else{
fprintf(stderr,"fork failed\n");
exit(1);
}
fprintf(stderr,"Exiting\n");
exit(1);
}
哪里./child:
bool cget_input(void){
char buffer[80], command[80];
fprintf(stderr,"Child trying receive from parent\n");
do{
if (!fgets(buffer, 20, stdin)) {
fprintf(stderr,"child failed to receive from parent\n");
return false;
}
sscanf(buffer, "%s", command);
if(strcmp(buffer, "A") == 0){
fprintf(stderr,"Child received 'A' from Parent and sending out 'B'\n");
fprintf(stdout, "B");
}
continue;
}while(true);
}
int main ()
{
if(!cget_input()){
return 0;
}
return 1;
}
结果,parent 和 child 的标准输入都没有收到任何东西, 没通过
if (!fgets(buffer, 20, stdin))
谁能指出我的代码哪里出了问题? 谢谢,
您必须在分叉前设置管道。
以下是需要完成的顺序的概述:
- 使用 pipe() 创建管道
- 分叉
- Parent 和 child 各自关闭管道的正确末端。
- 如果需要,parent 和 child 可以使用 dup() 和 close() 重定向标准输出、标准输入
- 此时,您可以在 child 进程中 exec() 一个新程序,它不需要知道已经发生的重定向。
fork 后,parent 和child 是两个不同的进程,此时parent 无权修改child 的文件描述符。任何共享文件描述符都必须在派生之前设置。