代码仓库:https://gitee.com/tgwTTT/linux-learning-dai/tree/master/fifotest
匿名管道:
1.只能用于具有血缘关系的进程进行进程间通信(常用于父子)
思考:如果两个进程不相关,改如何进行通信
如:进程a打开了一个文件a
进程b也打开了文件a
内核中,操作系统会不会打文件a在内存中加载两次
答案是:不会!!
这也为我们命名管道奠定基础,是在两个文件里面进行通信读取
命名管道(Named Pipe,也叫 FIFO):
是一种 以文件形式存在于文件系统中 的进程间通信(IPC)机制。与匿名管道只能用于 亲缘进程 不同,命名管道允许任意两个无亲缘关系的进程 通过约定好的路径交换数据。
这是linux中的一种特殊文件管道文件,他不需要将内存刷新到磁盘,只需要去打开读取

mkfifo:创建一个管道文件
int ret = mkfifo("/tmp/myfifo", 0666);
if (ret == -1) perror("mkfifo");
return 0;
打开规则与阻塞行为
| open 模式 | 行为说明 |
|---|---|
| O_RDONLY | 阻塞直到有写端打开 |
| O_WRONLY | 阻塞直到有读端打开 |
| O_NONBLOCK | 立即返回,若无对应端则 open 失败(errno=ENXIO) |
| 不能用 O_RDWR | 会读回自己写的数据,失去管道意义 |
下面是实现一个简单的管道通信的例子:
class IpcFifo
{
public:
IpcFifo(const std::string& path,const std::string &name)
:_path(path),_name(name)
{
_fifoname=_path+"/"+_name;
umask(0);
//新建管道
int n=mkfifo(_fifoname.c_str(),0666);
if(n!=0){
std::cerr<<"mkfifo error"<
上面的类主要是一个管道文件的创建和销毁
class FileOper
{
public:
FileOper(const std::string& path,const std::string &name)
:_path(path),_name(name),_fd(-1)
{
_fifoname=_path+"/"+_name;
}
~FileOper(){}
void OpenForRead(){
_fd=open(_fifoname.c_str(),O_RDONLY);
if(_fd<0){
std::cerr<<"open error"<0){
std::cout<<"send sucessful"<0){
std::cout<<"client say "<0){
close(_fd);
}
}
private:
std::string _path;
std::string _name;
std::string _fifoname;
int _fd;
};
上面代码主要是对管道文件的文件操作,当拿到文件描述符后如何进行通信
与匿名管道对比:
| 特性 | 匿名管道 | 命名管道 |
|---|---|---|
| 存在位置 | 内存 | 文件系统 |
| 进程关系 | 亲缘 | 任意 |
| 生命周期 | 随进程 | 随文件 |
| 名称/路径 | 无 | 有 |
今天 的更新就到这里,如有错误欢迎评论区指出
评论
还没有任何评论,你来说两句吧!