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

LINUX14 进程间的通信 - 管道

管道

12.1命名管道

12.1.1命名管道(Named Pipe/FIFO)

命名管道克服了普通管道只能在亲缘进程间使用的限制。

特点

  • 在文件系统中有对应的文件名(遵循UNC命名规范)
  • 允许无亲缘关系的进程通信
  • 通过 mkfifo() 系统调用创建
  • 支持多对多通信模式

创建命名管道方法:

#include <sys/stat.h>// 创建命名管道mkfifo("/tmp/myfifo", 0666);

使用命名管道方法

#include<fcntl.h>int fd=open("/tmp/myfifo",O_WRONLY);//发送数据端int fd=open("/tmp/myfifo",O_RDONLY);//写入数据端

12.1.2管道读写规则深度理解

  1. 读端关闭:如果所有读端关闭,写端进程会收到SIGPIPE信号,导致进程终止
  1. 写端关闭:读端读取完所有数据后,read返回0,表示文件结束
  1. 原子性保证:当写入数据量不大于PIPE_BUF(通常512B-4KB)时,Linux保证写入的原子性。

示例两个进程进行通信:

接收端a.c文件如下:

int fd=open("fifo",O_RDONLY);printf("fd=%d\n",fd);char buff[128]={0};while(1){int n=read(fd,buff,127);if(n==0)break;printf("buff=%s",buff);}

发送端b.c文件如下:

void fun(int sig){printf("sig = %d \n",sig);signal(SIGPIPE,SIG_DFL);}int main(){signal(SIGPIPE,fun);mkfifo("fifo",0600);int fd=open("fifo",O_WRONLY);printf("fd=%d\n",fd);char buff[128]={0};while(1){fgets(buff,127,stdin);write(fd,buff,sizeof(buff));}return 0;}

12.1.3管道的工作原理与核心特性

  1. 单向通信:数据只能从写端 ( fd[1] ) 流向读端 ( fd[0] )。要实现双向通信,需要建立两个管道。
  1. 内核缓冲:数据在内核缓冲区中暂存。读进程从缓冲区读取数据,写进程向缓冲区写入数据。
  1. 同步与阻塞
  • 当读进程尝试读取一个空管道时,它会阻塞,直到有数据写入。
  • 当写进程尝试向一个已满管道写入数据时,它会阻塞,直到有空间可用。
  • 如果所有读端都已关闭,写进程会收到  SIGPIPE  信号,通常导致进程终止。
  1. 字节流导向:管道不维护消息边界,数据被视为连续的字节流。多次写入可能被一次读取,单次写入也可能被多次读取。

12.2 匿名管道

12.2.1匿名管道(Anonymous Pipe)

匿名管道(Anonymous Pipe)是Linux/Unix系统中一种最基本的进程间通信机制,主要用于具有亲缘关系的进程间数据传递,匿名管道通过内核缓冲区实现单向数据流,其本质是一个内核维护的环形队列(先进先出)。

关键特性:

  • 单向通信:数据只能从写端流向读端
  • 血缘关系限制:传统匿名管道只能用于父子进程等有亲缘关系的进程间
  • 内核缓冲区:默认大小通常为4KB或64KB,数据存储在内核内存中
  • 同步机制:读空管道会阻塞,写满管道也会阻塞

12.2.2匿名管道工作原理

创建与使用流程

创建管道:

int pipefd[2];//// pipefd[0]读端,pipefd[1]写端pipe(pipe1); // 父→子pipe(pipe2); // 子→父// 1. 创建管道if (pipe(pipefd) == -1) {perror("pipe创建失败");return 1;}

父子进程通信:

// 2. 创建子进程pid_t pid = fork();if (pid == 0) {// 子进程:关闭写端,读取数据close(pipefd[1](@ref);read(pipefd[0], buffer, sizeof(buffer));printf("子进程收到: %s\n", buffer);close(pipefd;} else {// 父进程:关闭读端,写入数据close(pipefd;write(pipefd[1], "Hello from parent!", 18);close(pipefd[1](@ref);}

文件描述符继承机制:当父进程调用 fork() 创建子进程时,子进程会继承父进程的文件描述符表,因此父子进程可以通过相同的文件描述符访问同一个管道。

12.2.3匿名管道关键特性

1. 缓冲区与容量

  • 默认大小:通常为4KB或64KB,可通过系统配置调整
  • 原子操作:写入量小于 PIPE_BUF (通常4KB)时可保证操作的原子性

2. 阻塞行为

匿名管道的读写操作具有特定的阻塞特性:

情况

读端行为

写端行为

管道空

阻塞等待

正常写入

管道满

正常读取

阻塞等待

写端关闭

读取剩余数据后返回0

-

读端关闭

-

收到SIGPIPE信号

3. 四种特殊情况的处理

  1. 所有写端关闭:读端读完数据后, read 返回0
  1. 写端未关闭但无数据:读端阻塞等待
  1. 所有读端关闭:写端会收到 SIGPIPE 信号
  1. 读端未关闭但管道满:写端阻塞等待

管道对比

特性维度

匿名管道 (PIPE)

命名管道 (FIFO)

共同点

本质

内核缓冲区

内核缓冲区(但有文件名)

都是内存中的缓冲区,以文件形式抽象

通信方向

半双工,单向流动

半双工,单向流动

单向通信,双向需两个管道

进程关系

必须具有亲缘关系

无需亲缘关系

-

数据模式

字节流,无消息边界

字节流,无消息边界

数据是连续的字节流

同步机制

阻塞I/O,读写空/满管道会阻塞

阻塞I/O,读写空/满管道会阻塞

内核提供同步,保证数据安全

生命周期

随进程创建和销毁

在文件系统中持久存在,直到被显式删除

进程退出会关闭其持有的描述符

创建方式

 pipe() 系统调用

 mkfifo() 函数或命令

-

可见性

仅限继承文件描述符的进程

文件系统可见,任何进程可访问

选择依据:

  1. 需要在有亲缘关系的进程(如父子进程)间传递数据时,优先考虑匿名管道
  1. 需要在无亲缘关系的任意进程间通信时,必须使用命名管道
  1. 对于需要高性能、大数据量共享的场景,可考虑共享内存;对于需要可靠、结构化消息传递的场景,可考虑消息队列或套接字。
http://www.dtcms.com/a/496550.html

相关文章:

  • 徐州城乡建设局网站金山网站建设公司
  • Java成长之路 | 技术专栏导航页
  • 知识就是力量——mode-red使用qq邮箱
  • 四川网站建设公司 会员登录制作动作游戏吧中文
  • 做网站价格需要多少钱Wordpress页面标签插件
  • YOLO-V3深度学习中的目标检测新高度
  • 找到M3U8直播源的方法
  • html5网站建设平台百度搜索关键词规则
  • 专业做公墓 陵园的网站三合一网站包含什么
  • 深度学习——基于 ResNet18 的图像分类训练
  • 西安公司建一个网站需要多少钱广告设计公司合同
  • Linux:11.线程概念与控制
  • 恋家网邯郸房产网站排名优化服务公司
  • 婚纱网站建设需求分析国外模板wordpress
  • 南阳理工网站建设专项培训网站建设方案
  • 便携气象站具备完整的气象观测能力
  • 杭州倍世康 做网站网站怎样制作 优帮云
  • 一级A视网站 一级做爰片网站建设类有哪些岗位
  • 永兴县网站建设服务商什么是网站设计与运营
  • Google Landmarks Dataset v2 (GLDv2):面向实例级识别与检索的500万图像,200k+类别大规模地标识别基准
  • 个人域名做企业网站企业seo的措施有哪些
  • 网站开发验收流程图网站建设合同详细
  • 上海做网站比较好的公司有哪些wordpress两栏响应式主题
  • 【Altium Designer实战操作】对网络端口名称采用全中文命名的可行性及其相关隐患研究
  • 可视化NS-3安装踩坑记录
  • 怎么看别人的网站有没有做301电商网站建设哪家公司好
  • 河北省建设注册中心网站html5网络公司网站模板
  • 4.类和对象(上)
  • 高端手机“探花”之争,AI会成为“胜负手”吗?
  • 福建省住房和城乡建设厅官方网站做网站挂广告赚多少