命名管道
由于基于fork机制,匿名管道的使用前提必须是父子进程或者有共同祖先的进程,但是若想让没有亲缘关系之间的进程之间进行通信,怎么做到呢?解决方案就是FIFO (First in, First out),又叫做命名管道,命名管道是一种特殊的文件类型,它在文件系统中是真实存在的,它的好处在于可以通过文件路径来识别管道,从而让没有亲缘关系的进程之间建立连接
命名管道的使用步骤
一、创建命名管道
有两种创建方式,
1.在命令行创建
mkfifo filename
2.命名管道也可以从程序里创建
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char* filename,mode_t mode)
filename:指定FIFO文件的名称
mode_t:是文件的权限
二、访问命名管道
注意:
1.不能以O_RDWR模式打开FIFO文件,管道是单向通信,要么读要么写,不可以同时
2.打开默认是阻塞式打开,在这种情况下一个进程写模式打开管道的时候,必须有另一个进程以读模式打开,或者相反,否则进程open函数阻塞,直到满足以上关系。所以说管道的建立必须是一个进程以读(r)的方式打开该文件,而另一个进程以写(w)的方式打开该文件,才会在这两个进程之间建立管道
与匿名管道的区别
相对于匿名管道,命名管道多了一步打开操作,其余的和匿名管道类似,
命名管道使用示例
1.创建管道
#include<stdio.h>
#include<sys/types.h>//mode_t 在这个文件里面
#include<sys/stat.h>
int main()
{
//文件类型 -普通文件 d目录文件 l链接文件 p管道文件
int ret = mkfifo("./myfifo",0777);
if(ret<0)
{
perror("fifo");
return 1;
}
printf("mkfifo OK!\n");
return 0;
}
2.server.c
//server.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
//按照只读方式 打开 将阻塞在读 直到另外一个按照写方式打开
int fd= open("./myfifo",O_RDONLY);
if(fd<0)
{
perror("open");
return 1;
}
printf("open ok\n");
while(1)
{
char buf[1024] ={0};
ssize_t read_size = read(fd,buf,sizeof(buf)-1);
if(read_size<0)
{
perror("read");
return 1;
//sleep(1);
//continue();
}
if(read_size==0)
{
printf("read done\n");
return 0;
//sleep(1);
//continue();
}
buf[read_size] = '\0';
//写的是有效个数
printf("client:%s", buf);
}
close(fd);
return 0;
}
3.client.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include<string.h>
int main()
{
int fd= open("./myfifo",O_WRONLY);
if(fd<0)
{
perror("open");
return 1;
}
while(1)
{
char buf[1024] ={0};
ssize_t read_size = read(0,buf,sizeof(buf)-1);
if(read_size<0)
{
perror("read");
return 1;
}
if(read_size==0)
{
printf("read done\n");
return 0;
}
buf[read_size] = '\0';
write(fd,buf,strlen(buf));
}
close(fd);
}
运行结果: