欢迎光临
我们一直在努力

Linux之进程间通信(三)--命名管道

命名管道

之前说到有血缘关系的进程可以实现管道通信

但是要是没有血缘关系的进程也可以进行管道通信的—这种管道就是命名管道

如果再来一个进程和当前进程一样打开同一个文件,文件的核心数据结构和缓冲区只会存在一份

那么怎么确定两个进程打开的文件是同一个文件???

只要访问同一个路径下的同一个文件,文件名+路径=唯一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

参数说明

  • pathname:文件路径字符串,可以普通文件、目录、命名管道 (FIFO)、设备文件。
  • statbuf:传出参数,传入struct stat结构体指针,内核会把文件全部属性填充到这个内存。
  • restrict:C 语言指针限定修饰符,告诉编译器两个指针不会指向同一块内存,用于编译器优化,写代码时可以直接忽略这个关键字。
  • 返回值

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

    打开文件

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

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

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

    server进行信息接收

    client进行发送信息

    注意

    再通信没有开始之前,如果读端打开但是写端没有打开,读端的open就会阻塞,直到write打开

    为什么呢??

    命名管道(FIFO)默认是阻塞模式。 管道本质是内核中的一块缓冲区,设计语义:管道必须同时存在读端、写端,open 调用才返回。

  • 服务端:open(fifo,O_RDONLY) 只读打开 此时内核发现:只有读文件描述符,没有任何写端打开这个管道。 open() 直接挂起(阻塞),让出 CPU,休眠,不返回。

  • 直到客户端执行:open(fifo,O_WRONLY) 只写打开。 内核看到:现在管道同时具备读端 + 写端。 此时两边的open()全部唤醒,函数返回,程序继续往下跑。

  • 赞(0)
    未经允许不得转载:171主机测评 » Linux之进程间通信(三)--命名管道
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址