【linux】命名管道

简介: 【linux】命名管道

1.命名管道原理

2.代码实现命名管道

首先认识一个函数,他可以形成一个命名管道

头文件:

#include <sys/types.h>
 #include <sys/stat.h>

函数体:

int mkfifo(const char *pathname, mode_t mode);

第一个参数是新建的命名管道放在哪个路径下的路径字符串,第二个参数为该文件的打开权限


同时shell提供指令 mkfifo +命名管道名也能形成管道,会新建在当前路径下


unlink函数实现删除管道

头文件:

#include <unistd.h>

函数体:

int unlink(const char *pathname);

参数为命名管道文件的所在路径


总规划

1.send.cc该进程进行发送数据

2.reception.cc该进程进行接收数据

3.namepipe.hpp该文件进行配置环境

4.makefile对两个.cc文件进行编译

1.makefile编写

.PHONY:all
all:send reception
send:send.cc
     g++ -o send send.cc -std=c++11
reception:reception.cc
     g++ -o reception reception.cc -std=c++11
.PHONY:clean
clean:
     rm -rf send reception

2.namepipe.hpp先完成命名管道的创建以及删除操作

我们使用cpp,可以用类来封装管道的创建以及删除

namepipe.hpp

#include<iostream>
#include <sys/types.h>  //mkfifo的头文件open头文件
#include<string>
#include <sys/stat.h>   //mkfifo的头文件open头文件
#include <unistd.h>     //unlink头文件/close头文件
using namespace std;
const string com_path="./myfifo";
#define Defaultfd -1
#define Creater 1
#define User 2
class Namepipe
{
public: 
Namepipe(const string &path,int who)
:_fifo_path(path)
,_id(who)
,_fd(Defaultfd)
{
 
 if(_id==Creater)
 {
  int ret=mkfifo(_fifo_path.c_str(),0666);
     if(ret!=0)
       {
        perror("mkfifo");
       }
       cout<<"creater create named pipe"<<endl;
 }
}
~Namepipe()
{
if(_id==Creater)
{
 int ret=unlink(_fifo_path.c_str());
 if(ret!=0)
    {
    perror("unlink");
    }
    cout<<"creater free namepipe"<<endl;
}
if(_fd!= Defaultfd)close(_fd);
}
private:
     const string _fifo_path;
     int _id;
     int _fd;
};

send.cc

#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
}

reception.cc

#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
}

3. send .cc文件,reception.cc打开命名管道文件,分配文件操作符

reception.cc

#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
 if(fifo.openforread())
   {
   cout<<"reception open name pipe done"<<endl;
  
   }
}

send .cc

#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
 {
  cout<<"send open namepipe done"<<endl;
 }
}

namepipe.hpp

为了更清楚的展示,没有写构造和析构

#define Read O_RDONLY
#define Write O_WRONLY
#define Basesize 1024
class Namepipe
{
   private:
   bool opennamepipe(int mode)
   {
   _fd=open(_fifo_path.c_str(),mode);
   if(_fd<0)
    return false;
    return true;
   }
public: 
bool openforread()
{return opennamepipe(Read);
}
bool openforwrite()
{
return opennamepipe(Write);
}
private:
     const string _fifo_path;
     int _id;
     int _fd;
};

该步骤完成后,如上图所示


4.send进程写入命名管道数据

send.cc

#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
 {
  cout<<"send open namepipe done"<<endl;
  while(true)
     {
     cout<<"please Enter>";
     string message;
     getline(cin,message);
     fifo.writenamepipe(message);
         
     }
 }
 return 0;
}

namepipe.hpp(只保留本步骤的)

#define Basesize 1024
class Namepipe
{
 
public: 
int writenamepipe(const string &in)
{
 return write(_fd,in.c_str(),in.size());
}
private:
     const string _fifo_path;
     int _id;
     int _fd;
};


5.reception进程读内核缓冲区的数据

namepipe.hpp

class Namepipe
{
public: 
int readnamepipe(string *out)
{
char buffer[Basesize];
int n=read(_fd,buffer,sizeof(buffer));
if(n>0)
{buffer[n]=0;
*out=buffer;
}
return n;
}
private:
     const string _fifo_path;
     int _id;
     int _fd;
};

reception.cc

#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
 if(fifo.openforread())
   {
   cout<<"reception open name pipe done"<<endl;
   
   while(true)
   {
   string message;
   int n=fifo.readnamepipe(&message);
   if(n>0)
   {
   cout<<"send say>"<<message<<endl;
   }
   else if(n==0)
   {
   cout<<"send quit,reception too!"<<endl;
   break;
   }
   else 
   {
   cout<<"fifo.readnamepipe error"<<endl;
   break;
   }
   }
   
   }
}


整体代码

reception.cc

#include"namepipe.hpp"
int main()
{Namepipe fifo(com_path,Creater);
 if(fifo.openforread())
   {
   cout<<"reception open name pipe done"<<endl;
   
   while(true)
   {
   string message;
   int n=fifo.readnamepipe(&message);
   if(n>0)
   {
   cout<<"send say>"<<message<<endl;
   }
   else if(n==0)
   {
   cout<<"send quit,reception too!"<<endl;
   break;
   }
   else 
   {
   cout<<"fifo.readnamepipe error"<<endl;
   break;
   }
   }
   
   }
}

send.cc

#include"namepipe.hpp"
int main()
{
Namepipe fifo(com_path,User);
if(fifo.openforwrite())
 {
  cout<<"send open namepipe done"<<endl;
  while(true)
     {
     cout<<"please Enter>";
     string message;
     getline(cin,message);
     fifo.writenamepipe(message);
         
     }
 }
 return 0;
}

namepipe.hpp

#include<iostream>
#include <sys/types.h>  //mkfifo的头文件open头文件
#include<string>
#include <sys/stat.h>   //mkfifo的头文件open头文件
#include <unistd.h>     //unlink头文件/close头文件
#include <fcntl.h>      //open头文件
using namespace std;
const string com_path="./myfifo";
#define Defaultfd -1
#define Creater 1
#define User 2
#define Read O_RDONLY
#define Write O_WRONLY
#define Basesize 1024
class Namepipe
{
   private:
   bool opennamepipe(int mode)
   {
   _fd=open(_fifo_path.c_str(),mode);
   if(_fd<0)
    return false;
    return true;
   }
public: 
Namepipe(const string &path,int who)
:_fifo_path(path)
,_id(who)
,_fd(Defaultfd)
{
 
 if(_id==Creater)
 {
  int ret=mkfifo(_fifo_path.c_str(),0666);
     if(ret!=0)
       {
        perror("mkfifo");
       }
       cout<<"creater create named pipe"<<endl;
 }
}
~Namepipe()
{
if(_id==Creater)
{
 int ret=unlink(_fifo_path.c_str());
 if(ret!=0)
    {
    perror("unlink");
    }
    cout<<"creater free namepipe"<<endl;
}
if(_fd!= Defaultfd)close(_fd);
}
bool openforread()
{
return opennamepipe(Read);
}
bool openforwrite()
{
return opennamepipe(Write);
}
int writenamepipe(const string &in)
{
 return write(_fd,in.c_str(),in.size());
}
int readnamepipe(string *out)
{
char buffer[Basesize];
int n=read(_fd,buffer,sizeof(buffer));
if(n>0)
{buffer[n]=0;
*out=buffer;
}
return n;
}
private:
     const string _fifo_path;
     int _id;
     int _fd;
};


目录
相关文章
|
2月前
|
存储 负载均衡 Linux
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(下)
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(下)
|
2月前
|
消息中间件 Unix Linux
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(上)
【Linux 系统】进程间通信(匿名管道 & 命名管道)-- 详解(上)
|
2月前
|
Linux
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
【Linux】命名管道的创建方法&&基于命名管道的两个进程通信的实现
|
4天前
|
消息中间件 负载均衡 Linux
【linux】匿名管道|进程池
【linux】匿名管道|进程池
5 0
|
27天前
|
Linux Shell
【Linux】管道
【Linux】管道
|
27天前
|
Linux Shell
【Linux】命名管道
【Linux】命名管道
|
1天前
|
Linux
Linux的top命令是什么,如何使用
【6月更文挑战第30天】Linux的top命令是什么,如何使用
6 1