多进程通信之管道运用
管道的概念:管道是基于文件描述符的通信方式,当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1],其中fd[0]固定用于读管道,而fd[1]固定用于写管道,这样就构成了一个半双工的通道
无名管道:他只能用于亲缘关系的进程的通信(也就是父子进程或者兄弟进程之间),半双工通信发送,对它的读写可以使用普通的read(),write()等函数。
有名管道:它可以是互不相关的两个进程实现彼此通信。可以当作普通文件一样操作,遵循FIFIO。
1、创建无名管道pipe()
代码分析:
/* pipe.c */ #include <unistd.h> #include <sys/types.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #define MAX_DATA_LEN 256 #define DELAY_TIME 1 int main() { pid_t pid; int pipe_fd[2]; char buf[MAX_DATA_LEN]; const char data[] = "Pipe Test Program"; int real_read, real_write; memset((void*)buf, 0, sizeof(buf)); if (pipe(pipe_fd) < 0) /* 创建管道 */ { printf("pipe create error\n"); exit(1); } if ((pid = fork()) == 0) /* 创建一子进程 */ { /* 子进程关闭写描述符,并通过使子进程暂停1秒等待父进程已关闭相应的读描述符 */ close(pipe_fd[1]); sleep(DELAY_TIME * 3); /* 子进程读取管道内容 */ if ((real_read = read(pipe_fd[0], buf, MAX_DATA_LEN)) > 0) { printf("%d bytes read from the pipe is '%s'\n", real_read, buf); } close(pipe_fd[0]); /* 关闭子进程读描述符 */ exit(0); } else if (pid > 0) { /* 父进程关闭读描述符,并通过使父进程暂停1秒等待子进程已关闭相应的写描述符 */ close(pipe_fd[0]); sleep(DELAY_TIME); if((real_write = write(pipe_fd[1], data, strlen(data))) != -1) { printf("Parent wrote %d bytes : '%s'\n", real_write, data); } close(pipe_fd[1]); /*关闭父进程写描述符*/ waitpid(pid, NULL, 0); /*收集子进程退出信息*/ exit(0); } }