Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当我破坏了管道的写入端时,管道是否终止?_C - Fatal编程技术网

C 当我破坏了管道的写入端时,管道是否终止?

C 当我破坏了管道的写入端时,管道是否终止?,c,C,我有一个创建两个子进程的父进程。第一个子级将写入管道,第二个子级将从管道中读取。5秒后,父级将终止第一个子级。所以它的写入端应该自动关闭,不是吗?。我需要第二个子节点自动终止,因为它使用管道,在第一个子节点终止后,管道也应该终止。我的问题是:当我杀死孩子1时,我怎么能强迫孩子2立即死亡?我不需要孩子2在孩子1死后打印一些东西,即使他在管道缓冲区中还有任何信息要读取。我应该使用管道2而不是简单的管道吗 void do_close(int fd){ if(close(fd) != 0){

我有一个创建两个子进程的父进程。第一个子级将写入管道,第二个子级将从管道中读取。5秒后,父级将终止第一个子级。所以它的写入端应该自动关闭,不是吗?。我需要第二个子节点自动终止,因为它使用管道,在第一个子节点终止后,管道也应该终止。我的问题是:当我杀死孩子1时,我怎么能强迫孩子2立即死亡?我不需要孩子2在孩子1死后打印一些东西,即使他在管道缓冲区中还有任何信息要读取。我应该使用管道2而不是简单的管道吗

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立即写出缓冲区,并且还应该考虑部分读/写的可能性