Linux——命名管道

embedded/2024/11/25 18:38:21/

管道特点

  • 只能用于具有具体祖先的进程之间的通信,通常,一个管道由一个进程创建,然后该进程调用fork,创建子进程,关闭相应的读写端,然后父子进程就可以通信了
  • 管道提供流式服务
  • 一般而言,进程退出,管道释放,所以管道的声明周期随进程
  • 一般而言,内核会对管道操作进行同步和互斥

在这里插入图片描述

创建命名管道

mkfifo :第一个参数是命名管道的路劲名,第二个参数是权限,mode_t 其实是对unsigned int 的封装
返回值:成功返回0,失败返回-1,错误码被设置
在这里插入图片描述

在这里插入图片描述

文件分类

  • -:普通文件
  • d:目录文件
  • b:块设备文件
  • c:字符文件
  • p:管道文件,上述图中所示
  • s:网络(socket)文件
  • l:链接文件

这时有一个问题,就是如何进行通信的。通信的前提就是看到同一份资源,只有看到同一份资源,才能进行通信。
而mkfifo一个库函数,就是通过第一个参数看到同一份资源的,我们都知道,每一个进程都有属于自己的PCB结构体,其中有一个指针指向了文件描述符表,文件描述符表的内容又指向了file结构体,其中file结构体中存放着文件的inode,属性信息等等

当另一个进程创建的时候,去访问同一份资源,最后的访问的文件内容其实只有一份,进程最后一访问的就是同一块缓冲区。

如保证两个不同的进程打开的是同一个文件??

linux文件路径 + 文件名就可以保证打开的是同一个文件
在这里插入图片描述

在这里插入图片描述

实验:

管道是具有同步和互斥的,当我们读取一个管道文件的时候,如果没有文件就会被阻塞住,当有文件就会被读出来
在这里插入图片描述

这里我用客户端和服务端来实验, 当我们的服务端受到了客户端发来的消息,它会去读取,通过调用read函数,其中同步由read系统调用函数来解决。
在这里插入图片描述

ssize_t read(int fd,void buf,size_t count)*
功能:将fd指向的文件中的count个传送到buf中
如果返回0,表示已经到文件末尾或是无可读取的数据。如果返回-1,代表读取不成功,错误码存入errno中。
fd:文件描述符
buf:所要读的内容
count:要读取的大小

客户端打开管道文件是通过open系统调用函数,open函数中,flags可以是O_RDONLY、O_WRONLY、O_NONBLOCK,但是不能是O_RDWR,因为管道是单向的
在这里插入图片描述
成功打开则返回文件描述符,失败返回-1
其中flags 是以什么方式打开。
O_RDONLY 只读方式
O_WDONLY只写方式
O_RDWR读写方式
O_APPEND在文件的末尾上追加
O_CREAT如果文件不存在就创建
mode是权限

server.cc

#include "comm.hpp"
#include "log.hpp"
#include <sys/wait.h>//这是从fd中拿到数据的函数
static void getMessage(int fd)
{char buffer[SIZE];while (true){memset(buffer, '\0', sizeof(buffer));// 这里sizeof-1  是因为系统接口,文件有自己的管理机制,OS不用去关心\0ssize_t s = read(fd, buffer, sizeof(buffer) - 1);if (s > 0){cout <<"[" << "pid:" << getpid() << "]" << " " << "client say:"<< " " << buffer << endl;}else if (s == 0){cout << "[" << "pid:" << getpid() << "]"  << " "<< "read end of file, client quit,server quit too" << endl;break;}else{// read failbreak;}}
}int main()
{//1.创建管道文件if(mkfifo(ipcPath.c_str(),MODE) < 0){perror("mkfifo fail");exit(1);}log("创建管道成功",Debug) << " | " <<  "Step 1" << endl;//2.正常的文件操作int fd = open(ipcPath.c_str(),O_RDONLY);if(fd < 0){perror("open");exit(2);}log("打开管道成功",Debug)<< " | " << "Step 2" << endl;int nums = 5; for(int i =0; i<nums; i++){pid_t id = fork();if(id == 0){//3.编写正常代码//child//从fd中拿到数据getMessage(fd);exit(1);}}for(int i =0; i<nums; i++){//阻塞式等待waitpid(-1,nullptr,0);}//4.关闭文件close(fd);log("关闭管道成功",Debug)<< " | " << "Step 3" << endl;//通信结束,关闭管道文件unlink(ipcPath.c_str());log("删除管道成功",Debug) << " | "<< "Step 4" << endl;return 0;
}

client.cc

#include "comm.hpp"
#include "log.hpp"int main()
{//1.获取管道文件int fd = open(ipcPath.c_str(),O_WRONLY);if(fd < 0) {perror("open");exit(1);}// 2.ipc过程string buffer;while(true){cout << "Please Enter Message Line ->";getline(cin,buffer);//向文件里面去写write(fd,buffer.c_str(),buffer.size());}//3.关闭文件close(fd);return 0;
}

实验结果:

在这里插入图片描述
最后的退出结果
在这里插入图片描述


http://www.ppmy.cn/embedded/34125.html

相关文章

UDP通信

文章目录 recvfrom和sendto函数UDP通信server和client流程UDP实现的并发服务器和客户端 recvfrom和sendto函数 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);sockfd&#xff1a; 套接字buf&#xff1a;缓冲…

PC端Discord设置代理2022

开始使用 方法非常简单&#xff0c;在此下载release.zip并解压version.dll https://github.com/aiqinxuancai/discord-proxy/releases​github.com/aiqinxuancai/discord-proxy/releases 将version.dll放在Discord.exe所在目录&#xff08;如Discord有更新&#xff0c;则可能…

自适应调节Q和R的自适应UKF(AUKF_QR)的MATLAB程序

简述 基于三维模型的UKF&#xff0c;设计一段时间的输入状态误差较大&#xff0c;此时通过对比预测的状态值与观测值的残差&#xff0c;在相应的情况下自适应调节系统协方差Q和观测协方差R&#xff0c;构成自适应无迹卡尔曼滤波&#xff08;AUKF&#xff09;&#xff0c;与传统…

Eclipse中开启服务,网页无法打开 运行程序显示404

一、eclipse中开启服务后&#xff0c;网页无法打开的问题 当你在eclipse中开启服务后&#xff0c;如果网页无法打开&#xff0c;可能是以下几个原因导致的&#xff1a; 1. 端口冲突&#xff1a;请确保你所使用的端口没有被其他程序占用。可以尝试更换一个未被占用的端口。 2…

Unity 性能优化之动态批处理(四)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、动态合批是什么&#xff1f;二、使用动态批处理1.打开动态合批2.满足条件 三、检查动态合批是否成功五、动态合批弊端总结 前言 动态批处理是常用优…

【AI】指定python3.10安装Jupyter Lab

家里电脑 13900K, bash 不识别pythoncmd可以,但是cmd似乎默认是python2.7这个是webrtc构建需要的.python3 则可以识别到但是版本是python3.12*多个版本如何通过制定的python3.10 的pip来安装软件,例如Jupyter Lab安装3.10 C:\Users\zhangbin\AppData\Roaming\Microsoft\Windo…

毕设:邮件分发系统

文章目录 前言一、登录1.邮箱登录2.账号登录 二、注册三、首页四、写邮件五、收邮件六、草稿箱七、垃圾箱八、已发送九、通讯录十、用户管理十一、邮件管理十二、登录日志总结 前言 分享一下邮件分发系统 一、登录 1.邮箱登录 2.账号登录 二、注册 三、首页 首页有邮件信息&…

【centos】vmware安装airflow流程

文章目录 1.下载系统https://mirrors.aliyun.com/centos/7/isos/x86_64/ 选择DVD20092.在VMware中&#xff0c;除了修改安装位置&#xff0c;其它选择默认安装centos73.用户名为root,登录4.网络适配器为桥接模式。5.使用命令消除显示器警告。6.安装anaconda6.1下载包&#xff1…