看起来您的代码将运行 4 个进程:一个进程分叉成 2 个,然后每个进程都使用 popen() 分叉。 popen() 不仅会创建一个管道,还会创建一个通过该管道连接的子进程,因此调用 popen() 的 2 个进程中的每一个都会创建一个子进程。
你应该决定如何去做:要么让 popen() 完成所有工作,但不要使用 fork(),或者让 pipe() 自己创建管道并使用 fork() - 这就是我的代码下面是。
还有一个很大的区别:popen() 不仅会 fork,还会在子进程中执行另一个程序。我的示例保留在同一个可执行文件中。如果你想在子进程中执行另一个程序,那么 popen() 会很有用,但是你不应该使用 fork()。
int fsd[2]; // write to fds[1], read from fds[0]
pipe(fds); // creates the pipe with read+write file descriptors in fds
id_t pid = fork();
std::string output_data;
if(pid < 0)
{
printf("Error\n");
}
else if(!pid)
{
close(fds[1]); // else we'll never detect end of input
FILE* process = fdopen(fds[0], "r");
char temp_data[128];
if(process)
{
while(fgets(temp_data, sizeof(temp_data), process))
{
output_data.append(temp_data);
}
}
pclose(process);
exit(1);
}
else
{
close(fds[0]); // just to clean up
FILE* process = fdopen(fds[1], "w");
std::string output_data;
char temp_data[128];
if(process)
{
fprintf(process, "5\n"); // your fwrite("5",...) worked by luck only
}
pclose(process);
}
最后,如果您希望您的进程启动另一个可执行文件,写入该可执行文件然后从中读取,您需要这样做:
创建 2 个管道,一个用于从父级写入子级,一个用于从子级向父级回写,然后做一些魔术重新分配文件描述符:
int p2c[2]; pipe(p2c); // parent to child
int c2p[2]; pipe(c2p); // child to parent
if(fork()) { // parent - I ignore error checks here
close(p2c[0]); // the child reads from that
close(c2p[1]); // the child writes to that
FILE * f_w = fdopen(p2c[1],"w");
... write some data to the child using f_w ...
fclose(f_w);
FILE * f_r = fdopen(c2p[0],"r");
... read some data from the child using f_r ...
fclose(f_r);
wait(0); // just to avoid a zombie
} else { // in the child, change stdin and stdout
close(p2c[1]); close(0); dup(p2c[0]); close(p2c[0]);
close(c2p[0]); close(1); dup(c2p[1]); close(c2p[1]);
... now use execv or something similar to run the other executable
}