C 当我破坏了管道的写入端时,管道是否终止?
我有一个创建两个子进程的父进程。第一个子级将写入管道,第二个子级将从管道中读取。5秒后,父级将终止第一个子级。所以它的写入端应该自动关闭,不是吗?。我需要第二个子节点自动终止,因为它使用管道,在第一个子节点终止后,管道也应该终止。我的问题是:当我杀死孩子1时,我怎么能强迫孩子2立即死亡?我不需要孩子2在孩子1死后打印一些东西,即使他在管道缓冲区中还有任何信息要读取。我应该使用管道2而不是简单的管道吗C 当我破坏了管道的写入端时,管道是否终止?,c,C,我有一个创建两个子进程的父进程。第一个子级将写入管道,第二个子级将从管道中读取。5秒后,父级将终止第一个子级。所以它的写入端应该自动关闭,不是吗?。我需要第二个子节点自动终止,因为它使用管道,在第一个子节点终止后,管道也应该终止。我的问题是:当我杀死孩子1时,我怎么能强迫孩子2立即死亡?我不需要孩子2在孩子1死后打印一些东西,即使他在管道缓冲区中还有任何信息要读取。我应该使用管道2而不是简单的管道吗 void do_close(int fd){ if(close(fd) != 0){
void do_close(int fd){
if(close(fd) != 0){
perror("close");
exit(2);
}
}
void signalhandler(int signum){
fprintf(stderr, "f1 terminated!\n");
exit(1);
}
int main(){
pid_t f1 = -1, f2 = -1;
int pipefd[2];
if(pipe(pipefd) == -1){
perror("pipe");
exit(2);
}
f1 = fork();
if(f1 > 0){
f2 = fork();
}
if(f1 > 0 && f2 > 0){
do_close(pipefd[0]);
do_close(pipefd[1]);
sleep(5);
kill(f1, SIGTERM);
waitpid(f1, NULL, 0);
waitpid(f2, NULL, 0);
}
else if(f1 == 0){
signal(SIGTERM, signalhandler);
do_close(pipefd[0]);
while(1){
fflush(stdout);
write(pipefd[1], "Hello world!\n", 13);
sleep(1);
}
}
else if(f2 == 0){
do_close(pipefd[1]);
char *buf = (char*)malloc(13);
while(read(pipefd[0], buf, 13) > 0){
for(int i = 0; i < 13; i++){
printf("%c", buf[i]);
}
sleep(3);
}
}
return 0;
}
Terminated不是管道的常用术语,它可能会引起一些误解。如果缓冲区中仍有数据,则读卡器不会立即感觉到写入过程的终止 总结一下这个程序,您有一个进程以每秒1行的速率写入管道5秒钟,然后停止。另一个进程以每3秒1行的速率读取管道,直到EOF或error,然后退出 这些行很小,大小固定,因此不可能读取不完整的行 程序中的任何内容都不会导致管道出错,因此第二个子进程将一直读取到EOF 当满足两个条件时,管道上会发生EOF:没有写入程序,缓冲区为空。第一个子进程的死亡完成了第一个条件。第二个条件不是立即成立的,因为在5秒标记处,有5行写入管道,其中只有2行在开始时读取,3秒后读取 第二个子进程继续读取,拉入其余的行,并最终在大约5*3=15秒后退出
计时不是无限精确的,因此不能保证向管道写入5行。当我运行它时,我得到了6。你的问题是什么?你只能通过读取管道中仍然缓冲的所有字节,然后读取0字节,表示EOF来检测写入端是否关闭。当您观察到,通过调用exit显式终止第二个子项时,您的第二个子项将自动终止,即,通过检测零读取,只是由于sleep3行,它将在f1结束后保持从管道缓冲区读取一段时间,直到到达管道缓冲区的末尾。顺便说一句,您可以使用fwrite立即写出缓冲区,并且还应该考虑部分读/写的可能性