int main() { int pfd[2]; char test[10] = "hello"; pid_t pid; int n = 0; int status; pipe(pfd); pid = fork(); if (pid == 0) { close(pfd[0]); //while (1); n = write(pfd[1], test, 10); printf("child:n = %d\n", n); } else { wait(&status); printf("father: status = %d\n", status); } return 0; }
先在父进程中创建管道,然后创建子进程,子进程复制了父进程管道文件的文件描述符,所以父进程和子进程各具有2个管道描述符,当在子进程中关闭读端, 这时关闭的是子进程中管道文件的读端,而父进程的读端没有关闭,这时子进程往写段写数据的时候,因管道读端未完全关闭,所以父进程不会收到SIGPIPE的信号。
打印结果为
child: n = 10
father: status = 0
把子进程中的注释while打开,运行程序后观察进程中文件打开和关闭的详细信息
父进程 0 1 2 3 4
子进程 0 1 2 4
int main() { int pfd[2]; char test[10] = "hello"; pid_t pid; int n = 0; int status; pipe(pfd); pid = fork(); close(pfd[0]); if (pid == 0) { //while (1); n = write(pfd[1], test, 10); printf("child:n = %d\n", n); } else { wait(&status); printf("father: status = %d\n", status); } return 0; }
先在父进程中创建管道,然后创建子进程,然后关闭读端, 这时,父子进程的读端都关闭了,在子进程中往管道里写数据,打印结果如下
father: status = 13
证明子进程是由信号13(SIGPIPE)关闭的
把注释的while去掉,查看进程的详细信息
父进程 0 1 2 4
子进程 0 1 2 4
int main() { int pfd[2]; char test[10] = "hello"; pid_t pid; int n = 0; int status; pipe(pfd); pid = fork(); if (pid == 0) { close(pfd[0]); //while (1); n = write(pfd[1], test, 10); printf("child:n = %d\n", n); } else { wait(&status); printf("father: status = %d\n", status); } return 0; }
先在父进程中创建管道,然后创建子进程,子进程复制了父进程管道文件的文件描述符,所以父进程和子进程各具有 2个管道描述符,当在子进程中关闭读端, 这时关闭的是子进程中管道文件的读端,而父进程的读端没有关闭, 这时子进程往写段写数据的时候,因管道读端未完全关闭,所以父进程不会收到SIGPIPE的信号。 打印结果为 child: n = 10 father: status = 0 把子进程中的注释while打开,运行程序后观察进程中文件打开和关闭的详细信息 父进程 0 1 2 3 4 子进程 0 1 2 4
int main() { int pfd[2]; char test[10] = "hello"; pid_t pid; int n = 0; int status; pipe(pfd); pid = fork(); if (pid == 0) { close(pfd[0]); //while (1); n = write(pfd[1], test, 10); printf("child:n = %d\n", n); } else { //sleep(2); close(pfd[0]); wait(&status); printf("father: status = %d\n", status); } return 0; }
子进程和父进程把读端都关闭了, 所以打印结果
father: status = 13
若把sleep(2)的注释去掉,延迟父进程读端的关闭,打印结果则为
child: n = 10
father: status = 0