FIFO简介
FIFO就是Unix的一种复合POSIX标准的进程间通信机制。他又称为命名管道,跟管道的不同点是,每个FIFO都有一个路径名与之关联。
FIFO虽然有路径名,但是他这中文件是在内核态(管道也是在内核态),跟文件系统没有关系。
单个服务器进程,多个客户端进程与服务器进通信。客户端进程想服务器进程发送请求(客户端进程通过write写FIFO),服务端处理(通过read读客户进程的请求)之后返回相应内容(通过write写入专用FIFO)。
单个服务器进程多个客户端进程通信框架
客户进程和服务器进程都知道专用FIFO的路径名,关键是怎样创建客户和服务器进程专用的FIFO。因为,一个系统的进程id是确定的并且互斥,所以我们可以通过进程id去寻找FIFO,客户进程和服务进程之间的FIFO用进程id来创建,在客户和服务器进程之间协商一个格式(比如“fifo.pid”格式)。
多个客户进程向服务器进程请求服务
本示例代码,实现的是将客户进程请求打开一个文件,具体就是客户进程传文件名,服务器进程将文件内容返回。
客户端代码:

1 /* 2 * client.c 3 * 4 * Created on: Nov 2, 2016 5 * Author: sujunjun 6 */ 7 8 9 #include<stdio.h> 10 #include<unistd.h> 11 #include<sys/stat.h> 12 #include<limits.h> 13 #include<fcntl.h> 14 #include<stdlib.h> 15 #include<errno.h> 16 #include<string.h> 17 18 #define FIFO_SERVER "fifo.server" 19 #define SIZE PIPE_BUF 20 #define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) 21 22 int main(){ 23 24 pid_t pid=getpid(); 25 char buf[SIZE]; 26 char client_fifo_name[SIZE];//from server 27 snprintf(client_fifo_name,sizeof(client_fifo_name),"fifo.%ld",(long)pid); 28 if(mkfifo(client_fifo_name,FILE_MODE)<0 && errno!=EEXIST){ 29 printf("mk error "); 30 exit(1); 31 } 32 snprintf(buf,sizeof(buf),"%ld ",(long)pid); 33 int len=strlen(buf); 34 char *pathname=buf+len; 35 fgets(pathname,SIZE-len,stdin); 36 len =strlen(buf);/f include 37 38 int writefd=open(FIFO_SERVER,O_WRONLY); 39 write(writefd,buf,len-1);//len-1==not include 40 41 int readfd=open(client_fifo_name,O_RDONLY); 42 int r; 43 while((r=read(readfd,buf,SIZE))>0){ 44 write(STDOUT_FILENO,buf,r); 45 } 46 close(readfd); 47 unlink(client_fifo_name);//delete this temp file 48 return 0; 49 }
服务器代码:

1 /* 2 * server.c 3 * 4 * Created on: Nov 2, 2016 5 */ 6 7 #include<stdio.h> 8 #include<unistd.h> 9 #include<sys/stat.h> 10 #include<errno.h> 11 #include<stdlib.h> 12 #include<fcntl.h> 13 #include<limits.h> 14 #include<string.h> 15 16 #define FIFO_SERVER "fifo.server"//all known 17 18 #define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) 19 20 #define SIZE PIPE_BUF 21 int main(){ 22 if(mkfifo(FIFO_SERVER,FILE_MODE)<0 && errno!=EEXIST){ 23 printf("mk error "); 24 exit(1); 25 } 26 27 int readfd=open(FIFO_SERVER,O_RDONLY); 28 int writefd=open(FIFO_SERVER,O_WRONLY); 29 30 if(readfd==-1||writefd==-1){ 31 printf("open error "); 32 exit(1); 33 } 34 35 int r;char buf[SIZE];char *pathname;pid_t pid;char client_fifo_name[SIZE]; 36 while((r=read(readfd,buf,SIZE))>0){ 37 buf[r]='