命名管道
(基于文件+inode 的进程间通信方案)
首先我们要清楚,多个进程可以同时打开多个普通文件,OS 会为每一个进程都创建一个 struct file,但是多个进程共享同一份 inode、文件缓冲区和操作方法集,所以只会加载一次文件的属性和内容到 struct file 的 inode 和文件缓冲区中,这和父进程打开一个匿名管道并 fork 一个子进程后父子进程的行为类似。
命名管道就是从上面的普通文件改造而来,最直观的区别就是进程对命名管道的文件缓冲区写数据时,数据不会刷新到磁盘中。
命名管道的操作
指令操作
下面是创建命名管道的指令:
为什么命管道叫做 fifo 呢?其实管道本质就是一个队列,因为它有先进先出的特性。
我们可以看到,mkfifo 创建出来的文件的类型是 p,也就是管道文件。
下面我们来尝试用管道来传输数据:
代码操作
Makefile
我们创建两个独立的文件:client.cpp,server.cpp 分别表示客户端和服务端。接下来写 Makefile:
这里 Makefile 其实不能实现我们想要的——client.cpp,server.cpp 分别编译并生成两个可执行程序,最后只会生成一个可执行程序。
这是因为 Makefile 本身一次只会形成一个可执行程序,运行时会从上往下扫描,把遇到的第一个目标文件形成可执行程序。
所以我们需要先创建一个只有依赖关系没有依赖方法的伪目标 all,它依赖两个可执行程序:client,server,这样 Makefile 从上往下扫描时遇到的第一个目标文件就是 all,然后就会执行 all 依赖关系中的 client,server,这样就能一次创建两个可执行程序了。
all: client server
client: client.cpp common.hpp
g++ -o client client.cpp
server: server.cpp common.hpp NamedPipe.hpp
g++ -o server server.cpp
clean:
rm -f client server
创建命名管道
下面是代码层面场景命名管道的库函数调用接口:
因为进程间通信需要不同的进程看到同一份资源,所以我们再创建一个 common.hpp 文件,把客户端和服务端共享的内容都放到 common.hpp 中。
#ifndef __COMMON_HPP__
#define __COMMON_HPP__
#include <iostream>
#include <string>
#include <sys/types.h>
#
std::string fifoname = ;
mode = ;


