一、匿名管道和命名管道的区别
- 匿名管道由pipe函数创建并打开。
- 命名管道由mkfifo函数创建,打开用open
FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。
一、创建命名管道的函数
#include <sys/stat.h>// 返回值:成功返回0,出错返回-1int mkfifo(const char *pathname, mode_t mode);
pathname指创建出来的管道的路径和管道名,mode指创建出来的管道的权限,这里的权限和文件的权限是一样的。
二、删除命名管道的函数
#include <unistd.h>// 返回值:成功返回0,出错返回-1int unlink(const char *pathname);
pathname指创建出来的管道的路径和管道名,unlink也可以用来删除一般的文件。
三、利用命名管道实现两个进程之间的简单通信
这个通信将实现写端发送信息读端接收信息。更多地实现细节会在代码中以注释的方式给出。
3.1、头文件
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <cstdio>using namespace std;#define MODE 0666 //权限
#define NAME "./fifo.txt"//定义命名管道结构体
class Fifo
{
private:string _name; // 文件路径加文件名
public:Fifo(const string &name): _name(name){int n = mkfifo(_name.c_str(), MODE);if (n == 0)cout << "创建管道成功!" << endl;elsecout << "创建管道失败!原因是:" << strerror(errno) << endl;};~Fifo(){int n = unlink(_name.c_str());if (n == 0)cout << "删除管道成功!" << endl;elsecout << "删除管道失败!原因是:" << strerror(errno) << endl;};
};
3.2、接收方(Server)
#include "namedPipe.hpp"int main()
{Fifo fifo(NAME);//打开文件,打开成功返回文件描述符,打开失败返回-1int rfd = open(NAME, O_RDONLY);if (rfd < 0){cout << "文件打开失败,原因是:" << strerror(errno) << endl;return 1;}cout << "文件打开成功!" << endl;while (true){char buffer[1024];//读端不退,read函数会一直阻塞等待,读端退出read读到0ssize_t n = read(rfd, buffer, sizeof(buffer) - 1);if (n > 0){buffer[n] = '\0';cout << "客户说:" << buffer << endl;}else if (n == 0){cout << "客户退出了,我也退出了";break;}else{cout << "读取出错!原因是:" << strerror(errno) << endl;break;}}close(rfd);return 0;
}
3.3、发送方(Client)
#include "namedPipe.hpp"int main()
{int wfd = open(NAME, O_WRONLY);if (wfd < 0){cout << "文件打开失败,原因是:" << strerror(errno) << endl;return 1;}cout << "文件打开成功!" << endl;string buffer;while(true){cout << "请输入你的信息:" << endl;getline(cin, buffer);if(buffer == "quit")break;int n = write(wfd, buffer.c_str(), sizeof(buffer)-1);if(n < 0){cout << "输入错误,错误原因是:" << strerror(errno) << endl;}}close(wfd);return 0;
}