管道文件分为存在内存的无名管道和存在磁盘的有名管道,无名管道只能用于具有亲缘关系的进程之间,这就大大限制了管道的使用。而有名管道可以解决这个问题,他可以实现任意两个进程之间的通信。
有名管道的创建可以使用mkfifo函数,函数的使用类似于open函数的使用,可以指定管道的路径和打开的模式。
示例代码:
/*fifo_read.c*/ #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define FIFO "/tmp/myfifo" /*定义管道文件的目录文件名*/ #define STOP "stop" /*定义读取操作终止命令*/ int main(void) { /*读缓冲区*/ char buffer_read[100]; int fd; int bytes_read; /*调用mkfifo函数创建命名管道文件*/ if( (mkfifo(FIFO,O_CREAT | O_EXCL)) < 0 && (errno != EEXIST) ) { printf("Cannot create fifo file!\n\a"); exit(1); } printf("Preparing for reading bytes.....\n"); /*清0缓冲区数据*/ memset(buffer_read,0,sizeof(buffer_read)); /*以非阻塞的方式打开管道文件*/ fd = open(FIFO,O_RDONLY | O_NONBLOCK); if( fd == -1 ) { perror("Open:"); exit(1); } /*无限循环,每隔一秒读取管道文件,直到STOP命令到来*/ while(1) { memset(buffer_read,0,sizeof(buffer_read)); if( (bytes_read=read(fd,buffer_read,100)) == -1 ) { if( errno == EAGAIN ) printf("No data!\n\a"); } if( strcmp(STOP,buffer_read) ==0 ) break; printf("Read %s from FIFO!\n",buffer_read); sleep(1); } /*关闭并删除管道文件*/ unlink(FIFO); return 0; }
这是一个创建并读取管道的程序,下面是写入的程序:
/*fifo_write.c*/ #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define FIFO "/tmp/myfifo" /*定义管道文件的目录和文件名*/ int main(int argc,char *argv[]) { int fd; char buffer_write[100]; int bytes_write; if( argc == 1) { printf("Usage:%s string\n",argv[0]); exit(1); } /*以非阻塞的方式打开管道文件*/ fd = open(FIFO,O_WRONLY | O_NONBLOCK); if( fd == -1 ) { printf("Open error:no reading process!\n"); exit(1); } strcpy(buffer_write,argv[1]); if( (bytes_write=write(fd,buffer_write,100)) == -1 ) { if( errno == EAGAIN ) { printf("The FIFO has not been read!\n\a"); exit(1); } } else printf("Write %s to the FIFO!\n",buffer_write); return 0; }
为了更好的观察效果,需要把这两个程序分别放在两个终端里面运行,这里应该首先启动读程序,然后在写程序中输入内容,该内容会立即在读取的终端里面显示。