Ubuntu下Linux进程间通信——FIFO(有名管道)
Linux提供了多种进程间通信的方法,常见有管道(匿名)、FIFO(有名管道)、消息队列、信号量、共享内存,socket通信。
2.FIFO(有名管道)
我们通常所说的管道为无名管道或者匿名管道,管道没有名字,因此,只能在有亲缘关系的进程间(父子进程)实现通信,有名管道的出现突破了该限制,它是一个设备文件,它提供一个路径名与FIFO关联,即使进程与创建FIFO的进程不存在亲缘关系,只要可以访问这个路径也可以实现通信。
匿名管道与有名管道的区别
(1)有名管道可以进行无亲缘关系的进程间通信,但是管道只能用于有亲缘关系的进程间通信。
(2)创建并打开一个管道只需要pipe函数就够了,但是创建并打开FIFO需要在调用mkfifo后再调用open函数。
(3)管道在所有进程最终都关闭它之后自动消失,但是FIFO只有在调用unlink后才能从文件系统中删除。
实例
fifowrite.c
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FIFO_PATH "/tmp/fifo1"
int init_fifo(void)
{
//创建管道
if(access(FIFO_PATH, F_OK|W_OK ) != 0 )
{
if(mkfifo(FIFO_PATH, 0666 ) != 0 )
{
perror("mkfifo error ");
return -1 ;
}
}
//打开管道文件
int fd_fifo = open(FIFO_PATH, O_RDWR);
if (-1 == fd_fifo)
{
perror("open fifo error ");
return -1 ;
}
return fd_fifo;
}
int fifo_open(int fd_fifo)
{
fd_fifo = init_fifo();
if (-1 == fd_fifo)
{
printf(" init error \n");
return -1 ;
}
return fd_fifo;
}
int main()
{
int fd_fifo;
fd_fifo=init_fifo();
if(fd_fifo==-1)
{
printf("open fifo fail!\n");
return -1;
}
char *msg="hello fifo!\n";
write(fd_fifo,msg,strlen(msg));
return 0;
}
fiforead.c
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define FIFO_PATH "/tmp/fifo1"
int init_fifo(void)
{
//创建管道
if(access(FIFO_PATH, F_OK|W_OK ) != 0 )
{
if(mkfifo(FIFO_PATH, 0666 ) != 0 )
{
perror("mkfifo error ");
return -1 ;
}
}
//打开管道文件
int fd_fifo = open(FIFO_PATH, O_RDWR);
if (-1 == fd_fifo)
{
perror("open fifo error ");
return -1 ;
}
return fd_fifo;
}
int fifo_open(int fd_fifo)
{
fd_fifo = init_fifo();
if (-1 == fd_fifo)
{
printf(" init error \n");
return -1 ;
}
return fd_fifo;
}
int main()
{
int fd_fifo;
fd_fifo=init_fifo();
if(fd_fifo==-1)
{
printf("open fifo fail!\n");
return -1;
}
char buf[1024];
read(fd_fifo,buf,sizeof(buf));
printf("msg come from fifo: %s\n",buf);
return 0;
}