前文
一,什么是命名管道?
二,命名管道的基本原理
三,创建命名管道实现两个进程对写
四,匿名管道和命名管道的区别
总结
前文
上篇文章我们主要讲了匿名管道的定义以及基本原理,但是匿名管道有一个致命的缺陷,就是只能用于具有亲缘关系(有同一个祖先)的进程间的通信,而本文就是讲一下可以用于任意进程间通信的管道——命名管道
一,什么是命名管道?
命名管道其实就是一个特殊的文件,称为命名管道是因为在创建时需要加上名字,其中的内容是内存级别的专门用来进程间通信的,也就是说并不会保存到磁盘上面。
在linux中用下面的指令可以创建一个命名管道:
- mkfifo [管道名字]
如上图所示,左右两边是同一台机器同一个路径下,我们首先在左边创建了匿名管道,然后我们就成功创造出fifo的特殊文件,然后我们用echo将内容重定向到命名管道中,然后左边cat进行读取,成功读取,echo和cat两个进程成功通信
当然除了linux下指令的创建,在语言层操作系统也给我们提供了创建命名管道的接口,如下所示:
int mkfifo(const char *path,mode_t mode);
1.创建成功返回0,失败返回其他
2.path为所创建的目录以及管道的名字,如./fifo
3.mode为命名管道的初始权限
其具体用法如下:
int main(int argc, char *argv[])
{
mkfifo("./fifo", 0644);
return 0;
}
二,命名管道的基本原理
接下来我们讲一下命名管道的基本原理
如上图,进程1以写的方式打开命名管道fifo,然后进程2以读的方式打开命名管道fifo,经过os的优化,进程2会直接用已经被进程1打开的fifo,这样进程1和进程2就看到了同一个文件,就可以通过这个文件进行通信,然后进程1写入内容,进程2进行读取,这样两个进程就通过命名管道fifo实现了通信
三,创建命名管道实现两个进程对写
写端
#include <iostream>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <assert.h>
using namespace std;
int main()
{
//写方创造管道文件
int n=mkfifo("./fifo",0666);
if(n!=0)//创建失败
{
cout<<errno<<":"<<strerror(errno)<<endl;
return 1;
}
//以写的方式打开文件
int fd=open("./fifo",O_WRONLY);
assert(fd>=0);
//写入内容
while(true)
{
char buffer[1024];
char* ret=fgets(buffer,sizeof(buffer)-1,stdin);//从屏幕读取内容
//写入管道
size_t size=write(fd,buffer,strlen(buffer));
assert(size>=0);//判断是否成功写入
}
//关闭文件
close(fd);
return 0;
}
读端
#include <iostream>
#include <cerrno>
#include <cstring>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
using namespace std;
int main()
{
//直接以读的方式打开
int fd=open("./fifo",O_RDONLY);
assert(fd>=0);
//读取内容
while(true)
{
char buffer[1024];
size_t size=read(fd,buffer,sizeof(buffer)-1);
if(size>0)//读取有内容,打印内容
{
cout<<buffer<<endl;
}
else if(size=0)//读取数为0,说明写端不再写入,读端退出
{
cout<<"写端停止写入,读端退出"<<endl;
break;
}
else//读取异常退出
{
cout<<"读取异常"<<endl;
break;
}
}
//关闭
close(fd);
return 0;
}
运行效果
四,匿名管道和命名管道的区别
1. 匿名管道由pipe函数创建并打开。
2. 命名管道由mkfifo函数创建,打开用open
3. FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。
总结
本节命名管道讲完,管道的内容基本就结束了,如果兄弟们觉得有所收货可以给个三连鼓励一下