/*1 只有管道写端的引用计数变成0,才会关闭管道得写端. 2 进程结束后,自动关闭打开的文件 3 如果父进程先退出,而且没有调用wait等待子进程, 那么子进程就会变成僵死进程*/ #include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, const char **argv) { int len; pid_t pid; int pfd[2]; char buffer[1024] = {0}; if (pipe(pfd) < 0) { printf("pipe error\n"); exit(0); } if ((pid = fork()) < 0) { printf("fork error\n"); exit(0); } if (pid == 0) { /* 子进程 */ write(pfd[1], "hello\n", 6); // close(pfd[1]); sleep(2); } else { /* 父进程 */ close(pfd[1]); while ((len = read(pfd[0], buffer, 1023)) > 0) { buffer[len] = '\0'; printf("len = %d, %s", len, buffer); } printf("read done\n"); wait(0); /* 等待子进程退出才能看到效果 */ } return 0; } |
/* 如果父进程不关闭管道的写端, 即便子进程关闭了管道的写端, 还是会阻塞在read上 1)当读一个写端被关闭的管道时,所有数据都被读取后,read返回0,用于指示达到了文件结束处 这个程序可以很好地说明这一点,当注释掉parent中close(pfd[1]);后,程序就进入阻塞*/ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> int main(int argc, const char **argv) { int len; pid_t pid; int pfd[2]; char buffer[1024] = {0}; if (pipe(pfd) < 0) { printf("pipe error\n"); exit(0); } if ((pid = fork()) < 0) { printf("fork error\n"); exit(0); } if (pid == 0) { /* 子进程 */ close(pfd[1]); while ((len = read(pfd[0], buffer, 1023)) > 0) { buffer[len] = '\0'; printf("len = %d, %s", len, buffer); } } else { /* 父进程 */ close(pfd[0]); write(pfd[1], "hello\n", 6); // close(pfd[1]); wait(0); } return 0; } |
/* 当写一个读端被关闭的管道,则产生信号SIGPIPE。如果忽略该信号或者捕捉该信号并从其处理程序返回,则write返回-1,errno设置为EPIPE。
当用gdb运行时,可以发现当写一个读端被关闭的管道,会产生信号SIGPIPE*/
#include <sys/wait.h>#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #define MAXLINE 200 int main(void) { int n; int fd[2]; pid_t pid; char line[MAXLINE]; if(pipe(fd) < 0) printf("pipe error\n"); if((pid = fork()) < 0) printf("fork error\n"); else if(pid > 0 ){ close(fd[0]); while(1){ n = write(fd[1],"hello,world",MAXLINE); if(n <= 0){ printf("n <= 0\n"); break; } printf("parent n :%d\n",n); } waitpid(pid,0,0); }else{ printf("child\n"); close(fd[1]); n = read(fd[0],line,MAXLINE); write(STDOUT_FILENO,line,n); close(fd[0]); printf("close read end in child\n"); } exit(0); } |
/*父进程与子进程之间交互:父进程向子进程写入from parent process,子进程向父进程写入from child process*/ #include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, const char **argv) { int pfd2[2]; pid_t pid; int pfd1[2]; int n; char buffer1[1024] = {0}; char buffer2[1024] = {0} if ( (pipe(pfd1) < 0) || (pipe(pfd2) < 0) ) { printf("pipe error\n"); exit(0); } if ((pid = fork()) < 0) { printf("fork error\n"); exit(0); } if (pid == 0) { /* 子进程 */ close(pfd1[0]); write(pfd1[1],"from child process",1024); close(pfd1[1]); close(pfd2[1]); while((n = read(pfd2[0],buffer1,1024)) > 0 ) write(STDOUT_FILENO,buffer1,n); exit(1); } else { /* 父进程 */ close(pfd2[0]); write(pfd2[1],"from parent process",1024); close(pfd2[1]);
close(pfd1[1]);
while((n = read(pfd1[0],buffer2,1024)) > 0 )write(STDOUT_FILENO,buffer2,n); wait(0); } return 0; } |
#include <sys/wait.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(int argc, const char **argv) { int pfd2[2]; pid_t pid; int pfd1[2]; int n; char buffer1[1024] = {0},buffer2[1024]={0}; if ( (pipe(pfd1) < 0) || (pipe(pfd2) < 0) ) { printf("pipe error\n"); exit(0); } if ((pid = fork()) < 0) { printf("fork error\n"); exit(0); } if (pid == 0) { /* 子进程 */ close(pfd1[0]); write(pfd1[1],"from child process",1024); close(pfd1[1]); close(pfd2[1]); while((n = read(pfd2[0],buffer1,1024)) > 0 ){ buffer1[n]='\0'; printf("buffer1:%s\n",buffer1); } exit(1); } else { /* 父进程 */ close(pfd1[1]); close(pfd2[0]); write(pfd2[1],"from parent process",1024); close(pfd2[1]); while((n = read(pfd1[0],buffer2,1024)) > 0 ){ buffer2[n]='\0'; printf("buffer2:%s\n",buffer2); } wait(0); } return 0; } |