您的位置:首页 > 运维架构 > Linux

Linux下进程间通信之命名管道(FIFO)

2016-04-10 17:18 429 查看
匿名管道的一个不足之处是没有名字,因此,只能用于具有亲缘关系的进程间通信。在命名管道(FIFO)提出后,该限制得到了克服。FIFO不同于pipe在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。命名管道是一个设备文件,因此,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问该路径,就能够相互通信。

FIFO总是按照先进先出的原则工作,第一个被写入的数据将首先从管道中读出。
Linux下有两种方式创建FIFO,一是在shell下交互的建立一个命名管道,二是在程序中使用系统函数建立。
在这里我们使用系统函数mkfifo在程序中建立:
1):在写端创建一个命名管道,并在相同的路径下以只写的方式打开;
2):在读端以相同的路径以只读的方式打开该文件;
fifo read端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
int fd=open("./.tmp",O_RDONLY);
if(fd<0){
perror("open");
exit(1);
}
char buf[1024];
memset(buf,'\0',sizeof(buf));
while(1)
{
ssize_t _size=read(fd,buf,sizeof(buf));
if(_size<=0)
{
perror("read");
exit(2);
}
printf("%s\n",buf);

}
return 0;
}
fifo write端:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int _fifo=mkfifo("./.tmp",S_IFIFO | 0666);
if(_fifo<0)
{
perror("mkfifo");
exit(1);
}
int fd=open("./.tmp",O_WRONLY);
if(fd<0){
perror("open");
exit(2);
}
char buf[1024];
while(1)
{
memset(buf,'\0',sizeof(buf));
printf("you want to say:");
gets(buf);
fflush(stdout);
ssize_t _size=write(fd,buf,strlen(buf));
if(_size>0)
{
buf[_size]='\0';
}else{
perror("write");
exit(3);
}
}

return 0;
}

其运行结果:
写端:
you want to say:nihao
you want to say:jin tian tian qi zhehao
you want to say:ni zai na
you want to say:
读端:
nihao jin tian tian qi zhehao ni zai na
由此可见,文件系统中的路径名是全局的,各进程都可以访问,因此,可用文件系统中的路径名来标识一个IPC通道。并且它的行为和之前所讲的没有名字管道类似。由于Linuc下一切皆文件,所以对命名管道的使用也就变得与文件操作非常的统一,也使它的使用非常方便,同时我们也可以像平常的文件名一样在命令中使用 。

本文出自 “柏拉图的永恒” 博客,请务必保留此出处http://ab3813.blog.51cto.com/10538332/1762358
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: