无名管道
• 从最早的UNIX 系统开始,无名管道的通信方式就存在,有点类似硬
件中的串口,从最初的设计者定型之后,这种通信模型就一直延续到
今天,说明无名管道当初的设计就极具科学性
• 无名管道有一定的局限性
– 它是属于半双工的通信方式
– 只有具有“亲缘关系”的的进程才能使用这种通信方式,也就是父进程和
子进程之间
• man 2 pipe
• int pipe(int pipefd[2])
– 参数pipefd[0]:用于读管道
– 参数pipefd[1]:用于写管道
– 返回值:执行成功返回0,失败返回-1
• man 7 pipe
– 官方文档中的例程
• 编写编译运行测试
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> //进程读函数 void read_data(int *); //进程写函数 void write_data(int *); int main(int argc,char *argv[]) { int pipes[2],rc; pid_t pid; rc = pipe(pipes); //创建管道 if(rc == -1){ perror(" pipes "); exit(1); } pid = fork(); //创建进程 switch(pid){ case -1: perror(" fork "); exit(1); case 0: read_data(pipes); //相同的pipes default: write_data(pipes); //相同的pipes } return 0; } //进程读函数 void read_data(int pipes[]) { int c,rc; //由于此函数只负责读,因此将写描述关闭(资源宝贵) close(pipes[1]); //阻塞,等待从管道读取数据 //int 转为 unsiged char 输出到终端 while( (rc = read(pipes[0],&c,1)) > 0 ){ putchar(c); } exit(0); } //进程写函数 void write_data(int pipes[]) { int c,rc; //关闭读描述字 close(pipes[0]); while( (c=getchar()) > 0 ){ rc = write( pipes[1], &c, 1); //写入管道 if( rc == -1 ){ perror("Parent: write"); close(pipes[1]); exit(1); } } close( pipes[1] ); exit(0); }
有名管道
• 无名管道只能用于有亲缘关于的进程通信,有名管道可以实现无亲缘
关系的通信
• 有名管道fifo 给文件系统提供一个路径,这个路径和管道关联,只要
知道这个管道路径,就可以进行文件访问,fifo 是指先进先出,也就
是先写入的数据,先读出来
• 有名管道的读写速度非常快
• man 3 mkfifo
• int mkfifo(const char *pathname, mode_t mode)
– 参数*pathname:路径名,管道名称
– 参数mode:管道的权限
– 返回值:成功返回0,错误返回-1
• 编写编译运行测试
– 代码有点多,切分为多个视频
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include <string.h> void filecopy(FILE *ifp, char *buf); int main() { FILE *fp1; long int i = 100000; char buf[] = "I want to study Linux! "; char *file1 = "data.txt"; printf("begin! "); if((fp1 = fopen(file1, "a+")) == NULL) { printf("can't open %s ", file1); } while(i--) { filecopy(fp1, buf); } fclose(fp1); printf("over! "); return 0; } void filecopy(FILE *ifp, char *buf) { char c; int i,j; j = 0; i = strlen(buf) - 1; while(i--) { putc(buf[j], ifp); j++; } putc(' ',ifp); }
写管道
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define PIPE_BUF 1024 int main() { const char *fifo_name = "my_fifo"; char *file1 = "data.txt"; int pipe_fd = -1; int data_fd = -1; int res = 0; const int open_mode = O_WRONLY; int bytes_send = 0; char buffer[PIPE_BUF + 1]; if(access(fifo_name, F_OK) == -1) { //管道文件不存在 //创建命名管道 res = mkfifo(fifo_name, 0777); if(res != 0) { fprintf(stderr, "Could not create fifo %s ", fifo_name); exit(EXIT_FAILURE); } } printf("Process %d opening FIFO O_WRONLY ", getpid()); //以只写阻塞方式打开FIFO文件,以只读方式打开数据文件 pipe_fd = open(fifo_name, open_mode); data_fd = open(file1, O_RDONLY); printf("Process %d result %d ", getpid(), pipe_fd); if(pipe_fd != -1) { int bytes_read = 0; bytes_read = read(data_fd, buffer, PIPE_BUF); buffer[bytes_read] = '