进程间通信——有名管道
对于无名管道,它单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
对于有名管道,不同于无名管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文件定位操作。
有名管道特点:
1)对应管道文件,可用于任意进程间通信
2)打开管道文件时可以指定读写方式
3)通过文件IO操作,内容存放在内存中
1、有名管道的创建
用如下函数,可创建有名管道
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *filename, mode_t mode); //成功时返回0,失败返回EOF //filename为文件名,mode为文件读写权限,如0666
创建好有名管道后,就可以使用open、write、read访问有名管道。
2、例子
1)创建有名管道,往管道里写
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <string.h> 5 #include <fcntl.h> 6 int main(){ 7 8 int ret; 9 int fd; 10 char buf[32]; 11 unlink("/myfifo"); //删除路径名指定的文件 12 ret = mkfifo("/myfifo",0666); //创建有名管道 13 if(ret == -1) 14 { 15 perror("mkfifo "); 16 return -1; 17 } 18 /*创建只写文件*/ 19 fd = open("/myfifo",O_WRONLY); 20 if(fd<0) 21 { 22 perror("open "); 23 return -1; 24 } 25 /*写入内容*/ 26 strcpy(buf,"fifo write test"); 27 28 while(1) 29 { 30 write(fd,buf,strlen(buf)); 31 sleep(1); 32 } 33 }
2)从有名管道读
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <string.h> 5 #include <fcntl.h> 6 int main(){ 7 8 int ret; 9 int fd; 10 char buf[32]; 11 12 /*以只读方式打开文件*/ 13 fd = open("/myfifo",O_RDONLY); 14 if(fd<0) 15 { 16 perror("open "); 17 return -1; 18 } 19 20 /*从管道读出内容*/ 21 while(1) 22 { 23 memset(buf,0,32); 24 read(fd,buf,32); 25 printf("%s ",buf); 26 sleep(1); 27 } 28 }
在终端运行./fifo_test_write 每秒往管道写入内容。打开另一个终端,运行./fifo_test_read 从管道读内容,并打印到屏幕。