FIFO也称命名管道,是一种文件类型,在文件系统中可见到。管道由于没有名字,所以只能限定在亲缘关系的进程之间的通信。而通过FIFO任意进程之间都能够进行通信了。FIFO的特点如下:
- 命名管道可用于任何两个进程之间的通信,比管道灵活得多
- 命名管道作为特殊文件存在文件系统中,当进程使用结束后仍存在文件系统,需要“手动”删除
创建一个命名管道可以用mkfifo [管道名],删除可以用unlink [管道名实现]。当然用C程序创建一个管道文件也是很方便的。
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> int main(int argc, char **argv) { mode_t mode = 0666; if (argc != 2) { printf("Usage: ./mkfifo.out [NAME]\n"); exit(-1); } if ((mkfifo(argv[1], mode)) < 0) { printf("mkfifo error\n"); exit(-1); } printf("created"); return 0; }写命名管道代码如下:
#include<stdio.h> #include<stdlib.h> #include<fcntl.h> #include<sys/types.h> #include<limits.h> #include<string.h> #define BUFS PIPE_BUF void err_quit(char *msg) { printf("%s\n",msg); exit(-1); } int main(){ int fd; if ((fd = open("fifo",O_WRONLY)) < 0) { err_quit("open error"); } char buf[BUFS] = "Hello world"; write(fd,buf,strlen(buf)); return 0; }发送消息方式如下
#include<stdio.h> #include<stdlib.h> #include<fcntl.h> #include<sys/types.h> #include<limits.h> #include<string.h> #define BUFS PIPE_BUF void err_quit(char *msg) { printf("%s\n",msg); exit(-1); } int main(){ int fd; if ((fd = open("fifo",O_RDONLY)) < 0) { err_quit("open error"); } char buf[BUFS]; int len = read(fd,buf,BUFS); if (len < 0) { err_quit("read error"); } printf("Get: %s\n",buf); return 0; }上面的代码都很浅显易懂的,如果有进程读打开FIFO,且FIFO内没有数据,则对设置了阻塞标志的读操作来说,将一直阻塞,如果没有设置阻塞标志,则读操作会返回-1,errno的值是EAGAIN。尽管当前FIFO中有数据,只要别的进程读操作在进行时,本进程也会阻塞。
对于设置了阻塞标志的写操作,当要写入的数据量不大于PIPE_BUF时,将保证写入的原子性,当没有进程在读FIFO,那么设置了阻塞标志的写进程也会阻塞。