命名管道
之前说到有血缘关系的进程可以实现管道通信
但是要是没有血缘关系的进程也可以进行管道通信的—这种管道就是命名管道
如果再来一个进程和当前进程一样打开同一个文件,文件的核心数据结构和缓冲区只会存在一份
那么怎么确定两个进程打开的文件是同一个文件???
只要访问同一个路径下的同一个文件,文件名+路径=唯一inode
但是和之前的磁盘文件不同的是内核缓冲区不会刷新到磁盘
系统
mkfifo

mkfifo namedpipe

它拥有自己独立的inode,并且p->说明其为管道文件

但是他并不需要任何的磁盘空间
我们可以试一下往这个文件里面写入,再由另外一个进程进行读取

代码


.hpp 是 C++ 的头文件,全称 header‑plus‑plus。 简单理解:就是把 .h 头文件 + .cpp 实现写在同一个文件里面。
什么时候必须用 hpp???
C++ 模板 template(template 类、template 函数)必须写在头文件!
模板代码编译阶段实例化,编译器需要看到完整源代码,不能分离到 cpp。 这种场景最适合.hpp。
创建文件



如果我们再次运行我们就发现报错,因为这个文件已经存在,inode是唯一的

删除文件
我们除了可以用rm
也可以用unlink,他就是解除了文件和inode之间的映射

系统调用


再main函数里面创建后再删除


当然我们想要更加完善一点
文件创建前就检查文件是否存在,不存在则创建,存在就不创建,然后在进程结束时将管道文件删除
再创建管道的成员函数时,添加判断管道文件是否存在

判断管道是否存在的核心逻辑,用stat

参数说明
返回值
- 成功:返回0,文件信息存入statbuf
- 失败:返回‑1,设置 errno(文件不存在、权限不足等)



打开文件
这里打开文件和之前文件的操作类似,也是用open函数来进行实现

定义打开方式时写还是读打开

打开了文件,然后要接受信息和发送信息


server进行信息接收

client进行发送信息


注意
再通信没有开始之前,如果读端打开但是写端没有打开,读端的open就会阻塞,直到write打开
为什么呢??
命名管道(FIFO)默认是阻塞模式。 管道本质是内核中的一块缓冲区,设计语义:管道必须同时存在读端、写端,open 调用才返回。
服务端:open(fifo,O_RDONLY) 只读打开 此时内核发现:只有读文件描述符,没有任何写端打开这个管道。 open() 直接挂起(阻塞),让出 CPU,休眠,不返回。
直到客户端执行:open(fifo,O_WRONLY) 只写打开。 内核看到:现在管道同时具备读端 + 写端。 此时两边的open()全部唤醒,函数返回,程序继续往下跑。




