
1.1、创建及简单使用命令管道的创建依赖于函数mkfifo函数原型如下在这里插入图片描述代码语言javascriptAI代码解释#include sys/types.h #include sys/stat.h int mkfifo(const char *pathname, mode_t mode);关于mkfifo函数在这里插入图片描述对于参数1既可以传递绝对路径/home/xxx/namePipeCode/fifo也可以传递相对路径./fifo当然绝对路径更灵活但也更长对于参数2mode_t其实就是对unsigned int的封装等价于uint32_t而mode就是创建命名管道时的初始权限实际权限需要经过umask掩码计算不难发现mkfifo和mkdir非常像其实mkfifo可以直接在命令行中运行创建一个名为fifo的命名管道文件代码语言javascriptAI代码解释mkfifo fifo在这里插入图片描述p是管道文件大小为0在这里插入图片描述这个管道文件也非常特殊大小为0从侧面说明 管道文件就是一个纯纯的内存级文件有自己的上限出现在文件系统中只是单纯挂个名而已可以直接在命令行中使用命名管道echo可以进行数据写入可以重定向至fifocat可以进行数据读取同样也可以重定向于fifo打开两个终端窗口两个进程即可进行通信在这里插入图片描述命名管道遵循管道的四种场景因此在写端未写入数据时读端会阻塞当然也可以通过程序实现两个独立进程IPC思路创建服务端 server和客户端 client两个独立的进程服务端server创建并以读的方式打开管道文件客户端client以写的方式打开管道文件打开后俩进程可以进程通信通信结束后由客户端关闭写端服务端读端读取到 0 后也关闭并删除命令管道文件注意当管道文件不存在时文件会打开失败因此为了确保正常通信需要先运行服务端server创建管道文件服务端启动后因为是读端所以会阻塞等待客户端写端写入数据客户端写入数据时因为 ‘\n’ 也被读取了所以要去除此字符通信结束后需要服务端主动删除管道文件代码语言javascriptAI代码解释unlink 命令管道文件名 //删除管道文件为了让服务端和客户端能享有同一个文件名可以创建一个公共头文件 common.h其中存储命名管道文件名及默认权限等公有信息公共资源common.h代码语言javascriptAI代码解释#pragma once #include iostream #include string std::string fifo_name ./fifo; //管道名 uint32_t mode 0666; //权限服务端写端 server.cc 提供文件拷贝服务代码语言javascriptAI代码解释#include iostream #include cstring #include cerrno #include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h #include common.h using namespace std; int main() { // 服务端 // 1、打开文件 int wfd open(fifo_name.c_str(), O_WRONLY); if (wfd 0) { cerr open fail! errno: errno | strerror(errno) endl; exit(0); } // 2、打开源文件 FILE *fp fopen(file.txt, r); if (fp NULL) { cerr fopen fail! errno: errno | strerror(errno) endl; exit(0); } // 3、读取源文件数据 char buff[1024]; int n fread(buff, sizeof(char), sizeof(buff), fp); //IPC区域 // 4、写入源文件至命名管道 write(wfd, buff, strlen(buff)); cout 服务端已向管道写入: n 字节的数据 endl; //IPC区域 fclose(fp); fp nullptr; close(wfd); return 0; }客户端读端 client.cc 从服务端中拷贝文件下载代码语言javascriptAI代码解释#include iostream #include cstring #include cerrno #include unistd.h #include sys/types.h #include sys/stat.h #include fcntl.h #include common.h using namespace std; int main() { // 客户端 // 1、创建命名管道文件 int ret mkfifo(fifo_name.c_str(), mode); if (ret 0) { cerr mkfifo fail! errno: errno | strerror(errno) endl; exit(0