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

【无标题】无名管道

无名管道(Unnamed Pipe,也称为匿名管道)是 Unix/Linux 系统中最基础的进程间通信(IPC)机制之一,用于在有亲缘(亲缘)关系的进程(如父子进程、兄弟进程)之间进行单向问数据传输。

无名管道的核心特点

  1. 无标识:不像命名管道(FIFO)有文件系统中的路径标识,无名管道仅存在于内存中,进程通过文件描述符访问。
  2. 半双工:数据只能单向流动,如需双向通信需创建两个无名管道。
  3. 亲缘关系限制:仅能在父子进程、兄弟进程等有共同祖先的进程间使用(通过 fork 继承管道的文件描述符)。
  4. 面向字节流:数据按字节顺序传输,没有消息边界(类似 TCP 流)。
  5. 阻塞特性
    • 读端:管道为空时,读操作会阻塞,直到有数据写入。
    • 写端:管道满时,写操作会阻塞,直到数据被读取。
    • 若写端关闭,读端会读到 0(表示数据结束);若读端关闭,写操作会触发 SIGPIPE 信号(默认终止进程)。

无名管道的创建与使用

通过 pipe() 系统调用创建无名管道,函数原型:

#include <unistd.h>
int pipe(int pipefd[2]);
  • 参数 pipefd 是一个长度为 2 的数组,用于存储管道的两个文件描述符:
    • pipefd[0]:读端(接收数据)
    • pipefd[1]:写端(发送数据)
  • 返回值:成功返回 0,失败返回 -1 并设置 errno

使用流程(父子进程通信示例)

  1. 父进程调用 pipe() 创建管道。
  2. 父进程调用 fork() 创建子进程,子进程会继承管道的两个文件描述符。
  3. 关闭不需要的端(如父进程关闭读端,子进程关闭写端,实现父→子通信)。
  4. 通过 write() 写入数据,read() 读取数据。
  5. 通信结束后关闭管道描述符。

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>int main() {int pipefd[2];char buf[1024];// 1. 创建无名管道if (pipe(pipefd) == -1) {perror("pipe failed");return 1;}// 2. 创建子进程pid_t pid = fork();if (pid == -1) {perror("fork failed");return 1;}if (pid == 0) {  // 子进程:读数据close(pipefd[1]);  // 关闭子进程的写端(不需要)// 读取管道数据ssize_t n = read(pipefd[0], buf, sizeof(buf));if (n > 0) {printf("子进程收到:%.*s\n", (int)n, buf);}close(pipefd[0]);  // 关闭读端return 0;} else {  // 父进程:写数据close(pipefd[0]);  // 关闭父进程的读端(不需要)// 向管道写入数据const char *msg = "Hello from parent!";write(pipefd[1], msg, strlen(msg));close(pipefd[1]);  // 关闭写端(触发子进程读端返回0)return 0;}
}

无名管道的应用场景

  • 父子进程间的简单数据传递(如父进程向子进程传递配置参数)。
  • shell 中的管道命令(如 ls | grep "txt",通过无名管道连接 lsgrep 进程)。
  • 进程间的简单协同(如子进程完成任务后向父进程发送通知)。

与命名管道(FIFO)的核心区别

特性无名管道(Pipe)命名管道(FIFO)
标识方式仅通过文件描述符,无文件路径有文件系统路径(如 /tmp/myfifo
适用进程仅限亲缘关系进程任意进程(通过路径访问)
生命周期随进程退出而销毁存在于文件系统,需手动删除

总结:无名管道是一种轻量级的 IPC 机制,适用于亲缘进程间的简单单向通信,其设计简单、效率较高,但受限于亲缘关系和半双工特性,无法满足复杂通信场景。

http://www.lryc.cn/news/614617.html

相关文章:

  • NY128NY133美光固态闪存NY139NY143
  • 施耐德Twido PLC怎么实现远程上下载程序和编程配置?
  • F5发布业界首创集成式应用交付与安全平台,开启ADC 3.0新时代
  • 安全常见漏洞
  • openpnp - 不连接设备,只大概测试一下摄像头是否好使
  • Java中的方法引用操作符(::)详解与实战应用
  • Linux 运维与优化的系统化思维:从内核到生产环境的全链路管理
  • 【C++】类和对象--类中6个默认成员函数(2) --运算符重载
  • 笔试——Day32
  • 基于LLM的Chat应用测试方法探索:系统化评估与持续优化
  • 企业本地知识库助手 大模型+本地知识库
  • Prometheus 监控平台部署与应用
  • 【代码随想录day 14】 力扣 104.二叉树的最大深度
  • 三种 SSE 对比
  • 【LLM开发学习】
  • 十三、抽象队列同步器AQS
  • ClickHouse集群部署实践---3分片2副本集群
  • 【C#】掌握并发利器:深入理解 .NET 中的 Task.WhenAll
  • 宝龙地产债务化解解决方案一:基于资产代币化与轻资产转型的战略重构
  • MMBFJ310LT1G一款N沟道JFE 晶体管适用于高频放大器和振荡器等射频应用MMBFJ310LT1
  • 【vue】Vue 重要基础知识清单
  • 全面解析软件工程形式化说明技术
  • Vue 服务端渲染(SSR)详解
  • 页面tkinter
  • 初始化完数据库提示缺少server文件的处理方法
  • C 语言链表数据结构
  • 接口为什么要设计出v1和v2
  • 升级的MS9122S USB投屏控制芯片(HD输出)
  • Prometheus 通过读取文件中的配置来监控目标
  • 安科瑞EMS3.0:打造“零碳工厂”的智能能源神经中枢