管道实现通信的方式简单易懂,但一个不足之处就是管道没有名字,因此,只能用于具有亲缘关系的进程间通信,在命名管道(named pipe或FIFO)提出后,该限制得到了克服。FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存储于文件系统中。命名管道是一个设备⽂文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够通过FIFO相互通信。值得注意的是,FIFO(first input first output)总是按照先进先出的原则工作,第一个被写⼊入的数据将首先从管道中读出。
下面编写程序进行测试,程序分两部分,分别为读端和写端:
写端为server
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define _PATH_ "./fifo"
int main()
{
// 创建管道时需要在mode参数位置传S_IFIFO,表明创建的是命名管道
int ret = mkfifo(_PATH_, S_IFIFO | 0644);
if (ret < 0)
{
perror("mkfifo");
return 1;
}
int fd = open(_PATH_, O_WRONLY);
if (fd < 0)
{
perror("open");
return 2;
}
int time = 0;
char *msg = "hello world";
while (time++ < 100) //循环写入
{
write(fd, msg, strlen(msg));
sleep(1);
}
close(fd);
return 0;
}
读端为client
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define _PATH_ "./fifo"
int main()
{
int fd =open(_PATH_,O_RDONLY);
if(fd<0)
{
printf("open file error\n");
return 1;
}
int time=0;
char buf[100];
memset(buf,'\0',sizeof(buf));
while(time++<100)
{
int ret= read(fd,buf,sizeof(buf));
if(ret<=0)
{
printf("%s\n",buf);
break;
}
printf("%s\n",buf);
if(strncmp(buf,"quit",4)==0) //退出条件
break;
}
close(fd);
return 0;
}
先运行server端
在运行client端
client端不断接收到server端写入的信息。