要学习命名管道,我们必须首先对管道的特性有一定的了解,管道特性以及匿名管道链接
- 命名管道:管道的一个限制就是只能用在亲缘进程之间,如果我们想在不相关的进程间进行数据交换,可以使用FIFO文件来进行,它叫做命名管道。
命名管道:文件系统可见,是一个特殊类型(管道类型)的文件。命名管道可以应用在同一主机的任意进程间通信。
命名管道的创建:
(1)在命令行的创建
$ mkfifo filename;
(2)在程序里创建
int mkfifo(const char*filename,mode_t mode);//filename文件名,mode文件读写权限
(3)创建命名管道
int main(int argc,char*argv[])
{
mkfifo("p2",0644);//p2是管道名,0664是文件读写权限
return 0;
}
- 命名管道的打开规则
1.如果是只读打开管道FIFO
O_NONBLOCK disable:阻塞直到相应进程为写打开FIFO时
O_NONBLOCK enable:立即返回成功
2.如果是为写打开FIFO
O_NONBLOCK disable:阻塞直到相应进程为读打开FIFO时
O_NONBLOCK enable:立即返回失败,错误码为ENXIO
示例代码:
/*这是一个命名管道的实现,从命名管道中读取数据打印
* 1. 创建一个命名管道
* int mkfifo(const char*pathname,mod_t mod);
* pathname:管道的文件路径名字
* mod:管道文件的权限
* 成功返回0, 失败返回-1
* 2.打开管道open
* 3.从管道中读取数据
* 4.关闭管道文件close
*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
int main()
{
umask(0);
//为了防止因为管道文件存在失败
//1.创建命名管道
if(mkfifo("./test.fifo",0664)<0){
if(errno==EEXIST){
//文件存在
}
else{
perror("mkfifo error");
return -1;
}
}
//2.打开管道文件
//打开特性:如果以只读打开命名管道,那么open函数将阻塞等待,直到有其他进程以写的方式打开这个命名管道
//只写反之亦然
//如果文件以读写的方式发开,则不会阻塞
int fd=open("./test.fifo",O_RDONLY);
if(fd<0){
perror("open fifo error");
return -1;
}
printf("open fifo file success!!read start!\n");
while(1){
char buff[1024]={0};
int ret=read(fd,buff,1023);
if(ret>0){
printf("client say[%s]\n",buff);
}else if(ret==0){//如果所有写端被关闭,那么读取时返回0;
printf("all write point is close");
sleep(1);
}
}
close(fd);
return 0;
}
- 匿名管道和命名管道的区别
匿名管道由pipe函数创建并打开
命名管道由mkfifo函数创建,打开用open
他们唯一的区别就在创建于打开的方式不同,但他们的作用相 同。