我正在编写一个程序,它需要同时与外部程序进行双向通信,即同时读取和写入外部程序。
我创建了两个管道,一个用于向外部进程发送数据,一个用于从外部进程接收数据。在 fork 成为外部程序的子进程之后,父进程再次 fork。新的子进程现在将数据写入到外部程序的传出管道中,父进程现在从外部程序的传入管道中读取数据以进行进一步处理。
我听说使用 exit(3) 可能会导致缓冲区被刷新两次,但是我也担心使用 _exit(2) 可能会使缓冲区未刷新。在我的程序中,分叉前后都有输出。在这种情况下,我应该使用哪个 exit(3) 或 _exit(2)?
以下是我的主要功能。为简单起见,省略了#includes 和辅助函数。
int main() {
srand(time(NULL));
ssize_t n;
cin >> n;
for (double p = 0.0; p <= 1.0; p += 0.1) {
string s = generate(n, p);
int out_fd[2];
int in_fd[2];
pipe(out_fd);
pipe(in_fd);
pid_t child = fork();
if (child) {
// parent
close(out_fd[0]);
close(in_fd[1]);
if (fork()) {
close(out_fd[1]);
ssize_t size = 0;
const ssize_t block_size = 1048576;
char buf[block_size];
ssize_t n_read;
while ((n_read = read(in_fd[0], buf, block_size)) != 0) {
size += n_read;
}
size += n_read;
close(in_fd[0]);
cout << "p = " << p << "; compress ratio = " << double(size) / double(n) << '\n'; // data written before forking (the loop continues to fork)
} else {
write(out_fd[1], s.data(), s.size()); // data written after forking
exit(EXIT_SUCCESS); // exit(3) or _exit(2) ?
}
} else {
// child
close(in_fd[0]);
close(out_fd[1]);
dup2(out_fd[0], STDIN_FILENO);
dup2(in_fd[1], STDOUT_FILENO);
close(STDERR_FILENO);
execlp("xz", "xz", "-9", "--format=raw", reinterpret_cast<char *>(NULL));
}
}
}