当前位置: 首页 > news >正文

【linux进程间通信】无名管道

多用于具有亲缘关系的进程间进行单向通信

  • 特点:
  • 半双工通信,数据单向流动
  • 以字节流的方式通信,数据格式由用户自行定义
  • 多用于父子进程间通信,也可用于其他亲缘关系进程间通信
  • 实现原理:

父进程调用pipe函数会创建两个文件(读管道文件,写管道文件),这两个文件对应的文件节点为pipe inode, pipe inode为无名管道的具体实现

​ 父进程调用fork函数创建子进程,子进程拷贝父进程文件表,由于父子进程文件表内容相同,指向的file相同,所以最终父子进程操作的pipe管道相同。(父子进程都能看到管道内存空间,所以父子进程能正常通信)

由于对于无名管道来说,每次只能半双工工作,要么父进程写,子进程读;要么父进程读,子进程写。要想实现全双工的话,需要父进程调用两次pipe创建两个管道,如下图:

  • 注意:无亲缘关系进程文件表不能访问相同文件,进程间无法访问相同的pipe管道,所以不能通过无名管道进程通信。

  • 实现过程

无名管道操作

//建立无名管道 int pipe(int pipefd[2]); int pipe2(int pipefd[2], int flags); //读写无名管道 参考io关闭 ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); //关闭无名管道 int close(int fd);

功能

pipe或pipe2函数用于创建一个无名管道(pipe),用于进程间通信。

参数

pipefd:整型数组,用于存储管道的文件描述符。

  • pipefd[0]:读文件描述符。
  • pipefd[1]:写文件描述符。

flags:用于设置管道的标志位参数,可以是0或者以下下常量的安慰或:

O_NONBLOCK:设置非阻塞模式,即读取何写入管道时不会阻塞进程。 O_CLOEXEC:设置在execve系统调用执行的时候关闭管道

返回值

成功:返回0

失败:返回-1,并设置errno

  • 使用示例
int fd[2] = {0}; void test() { pid_t pid = fork(); //创建子进程 if(pid == 0) { close(fd[1]); //子进程关闭读写端 while(1) { char rbuf[100] = {0}; read(fd[0], rbuf, 100); //子进程读数据 } close(fd[0]); } else if(pid >0) close(fd[0]); //父进程关闭读端 } int main(int argc, char* argv[]) { pipe(fd); //创建pipe test(); while(1) { write(fd[1], TEST_STRING, sizeof(TEST_STRING)); //父进程写数据 sleep(1); } close(fd[1]); return 0; }
  • 使用无名管道实现父子进程通信
#include <unistd.h> #include <stdio.h> #include <string.h> int pipe_test() { int fd[2]; int ret = pipe(fd); if(ret = -1) { perror("pipe"); return -1; } ret = fork(); if(ret = 0) { //子进程 close(fd[0]); //子进程写数据,关闭 读 端 #define TEST_STRING "123456789" while(1) { write(fd[1], TEST_STRING, strlen(TEST_STRING)); sleep(1); } }else if(ret >0) { //父进程 close(fd[1]); //父进程读数据,关闭 写 端 while(1) { char* buf[1024]; read(fd[0], buf, 1024); printf("buf:%s\n", buf); } }else { } return 0; } int main(int argc, char* argv[]) { pipe_test(); return 0; }
http://www.jsqmd.com/news/463074/

相关文章:

  • 从原理到实践:深度解析Git克隆中的RPC failed错误及curl 18问题
  • 告别SQLite!用ObjectBox在Flutter中实现高性能本地存储的5个技巧
  • ESP32 WiFi吞吐量测试全攻略:从硬件选型到iperf实战(避坑指南)
  • java面试:springboot如何解决跨域问题
  • VisionPro模板匹配避坑指南:为什么你的CogPMAlignTool总识别失败?
  • all-MiniLM-L6-v2开箱即用:Ollama一键部署,立即体验轻量级嵌入模型
  • spring项目创建
  • 从零搭建电赛自动泊车小车:前轮转向架构选择与巡线PID调参心得
  • Debian新手必看:从安装到日常使用的保姆级教程(附常见问题解决方案)
  • Gemma-3-12B-IT在电商客服场景的应用:多轮商品咨询与售后话术生成
  • 从零开始:使用STM32CubeIDE完成你的第一个STM32项目(含调试技巧)
  • 阿里云轻量服务器部署 OpenClaw 完整教程
  • SpringBoot整合人大金仓KingBaseV8R6全攻略:从JPA配置到常见问题解决
  • Ubuntu20.04无网络环境下Docker离线安装全攻略(附详细包下载链接)
  • Unity标签隐藏功能大揭秘:如何用SerializeField和HideInInspector优化你的工作流
  • Ubuntu 22.04下英特尔AX200蓝牙失效?5分钟搞定驱动更新(附内核版本检查)
  • Lumerical FDTD实战:5步搞定光子晶体滤波器仿真(附三角晶格参数)
  • AI绘画新玩法:用z-image V7整合包实现精准姿势控制(附ControlNet实战技巧)
  • 避坑指南:STC15单片机ADC采集NTC温度时的5个常见问题及解决方法
  • VSCode+GDB调试内存泄漏?这个隐藏技巧帮你快速定位问题(附malloc_usable_size实战)
  • PyTorch实战:用DQN算法训练CartPole平衡杆(附完整代码与调参技巧)
  • 2026年阿里企业邮箱官方销售电话,最新报价指南与办理流程详细介绍 - 品牌2026
  • ACR122U-A9 NFC读写器实战:5分钟搞定智能海报制作(附Java环境配置指南)
  • Python配置管理神器OmegaConf:从YAML到Dataclass的完整实战指南
  • 从半导体到超导体:三种量子分布在实际工程中的应用对比
  • ThinkPad T14读卡器驱动安装全攻略:解决micro SD卡无法识别问题(附最新驱动下载)
  • Python开发中如何优雅地处理警告信息?warnings模块的5个实用技巧
  • 移动端主题切换动画:Material Design 动态效果实现
  • SAP财务模块实战:FAGLB03余额不一致的5种排查方法(附FAGLGVTR操作指南)
  • PyTorch实战:5分钟搞定CBAM注意力模块集成到ResNet(附完整代码)