常规的匿名管道通过pipe创建一片内存缓冲区,并对外提供两个文件描述符,用于只读或者只写操作。但其使用范围很小,只能用于父、子进程间的通信。因此Linux还提供有名管道的支持。
管道的本质是一片可以读写的缓冲区域,Linux将其描述为文件(UNIX思想:一切IO皆是文件) 对于有名管道,其主要特点是:
- 存在于文件系统中,包含文件名,管道文件被组织成树状结构
- 两个进程之间无需有联系,可以通过管道进行通信
- 对有名管道的操作和文件操作类似,支持读,写
【有名管道的创建】
mkfifo(const char* filename,mode) //创建指定名字的管道文件 并指明mode
int main()
{
if(mkfifo("./fifo_test",0777)<0)
{
cout<<"create fifo error"<<endl;
return -1;
}
cout<<" create success"<<endl;
return 0;
}
执行结果:
可以看到,通过mkfifo成功创建了fifo_test的管道文件,但其与磁盘上的普通文件不同,只是对缓冲区的一个抽象描述。
基于这个有名管道,fifo_test 可以通过其它进程来实现读写操作。
【写端】
首先通过access判断管道文件是否存在,如果不在,那么mkfifo创建一个管道文件。
然后,不断的接受stdin输入,并通过write写入到管道文件
当输入的字符为'q'时,结束程序
#include "stdio.h"
#include "stdlib.h"
#include<iostream>
#include <unistd.h>
#include <sys/stat.h>
#include "sys/types.h"
#include "fcntl.h"
using namespace std;
int main(int argc, char *argv[])
{
int i, ret, fd;
char p_flag = 0;
/* 创建有名管道 */
if (access("./myfifo", 0) < 0) { //先判断有名管道文件是否存在,不存在需要先创建
ret = mkfifo("./myfifo", 0777); //权限
if (ret < 0) {
cout<<"create fifo error"<<endl;
return -1;
}
cout<<"create fifo success"<<endl;
}
fd=open("./myfifo", O_WRONLY);//只写入方式
if (fd < 0) {
cout<<"open fifo error"<<endl;
return -1;
}
cout<<"open fifo success"<<endl;
char c;
while(cin>>c)
{
write(fd,&c,sizeof(c));
if(c=='q')
break;
}
return 0;
}
【读端】
首先通过access判断管道文件是否存在,如果不在,那么mkfifo创建一个管道文件。
然后,不断的通过read从管道读取字符,并显示。
当接收的字符为'q'时,结束程序
int main(int argc, char *argv[])
{
int i, ret, fd;
char p_flag = 0;
if (access("./myfifo", 0) < 0) { //先判断有名管道文件是否存在,不存在需要先创建
ret = mkfifo("./myfifo", 0777); //权限
if (ret < 0) {
cout<<"create fifo error"<<endl;
return -1;
}
cout<<"create fifo success"<<endl;
}
fd=open("./myfifo", O_RDONLY);//只读方式
if (fd < 0) {
cout<<"open fifo error"<<endl;
return -1;
}
cout<<"open fifo success"<<endl;
char c;
while(1)
{
read(fd,&c, sizeof(c));
cout<<c<<endl;//打印输出
if(c=='q')
break;
}
return 0;
}
g++ write.cpp -o write
g++ read.cpp -o read
分别启动写入端程序,读取端程序,运行结果:
由此可见,有名管道 named pipe 其主要特点是:
- 提供了一种多进程之间通信的方式,本质是多进程读取同一片内存缓冲区。
- 相较于匿名管道,由于采取了文件名标识,可以在不是父子进程关系之间通信。
- 对管道的读写操作与其它文件操作类似,Linux通过VFS进行抽象统一描述。(一切IO皆是文件思想)