FIFO就是Unix的一种复合POSIX标准的进程间通信机制。他又称为命名管道,跟管道的不同点是,每个FIFO都有一个路径名与之关联。

FIFO虽然有路径名,但是他这中文件是在内核态(管道也是在内核态),跟文件系统没有关系。

单个服务器进程,多个客户端进程与服务器进通信。客户端进程想服务器进程发送请求(客户端进程通过write写FIFO),服务端处理(通过read读客户进程的请求)之后返回相应内容(通过write写入专用FIFO)。

单个服务器进程多个客户端进程通信框架

进程间通信——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 \n");
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 \n
37 
38     int writefd=open(FIFO_SERVER,O_WRONLY);
39     write(writefd,buf,len-1);//len-1==not include \n
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 }
View Code

相关文章: