嵌入式第三十八篇——linux系统编程——IPC进程间通信

一、无名管道(Unnamed Pipe)

1. 核心定义

无名管道(简称pipe)是仅支持有亲缘关系进程(如父子、兄弟进程,由同一进程 fork 创建)间通信的临时 IPC 机制,无文件系统实体,仅存在于内存中。

2. 核心特性

  1. 半双工通信:数据只能单向流动,实际编程中通常按单工模式使用(如需双向通信,需创建两个管道)。

  2. 不支持定位操作 :管道是流式文件,无法使用lseek(文件 IO)或fseek(标准 IO)进行偏移定位。

  3. 文件操作方式 :

    • 首选文件 IO (open/read/write/close),无缓冲区,效率更高;
    • 可选标准 IO (fgets/fread/fgetc等),但存在缓冲区,需注意数据同步问题。
  4. 阻塞与异常行为 (关键):

    场景 行为
    读端存在,写端写入超过 64KB 写操作阻塞(管道缓冲区默认大小为 64KB)
    写端存在,管道为空时读操作 读操作阻塞(等待写端写入数据)
    读端关闭,写端继续写管道 管道破裂,写进程被信号终止(SIGPIPE)
    写端关闭,管道无数据时读操作 read返回 0(表示通信结束)

3. 编程接口

(1)创建管道函数
复制代码
#include <unistd.h>
int pipe(int pipefd[2]);
  • 功能:创建并打开一个无名管道,返回两个文件描述符。
  • 参数 :pipefd[0]为管道的读端 (固定),pipefd[1]为管道的写端(固定)。
  • 返回值 :成功返回 0,失败返回 - 1(并设置errno)。

4. 编程步骤

  1. 创建管道 :调用pipe()函数生成读、写端文件描述符。
  2. 创建子进程 :调用fork()生成子进程(子进程继承管道描述符)。
  3. 关闭无用端:父子进程分别关闭不需要的读 / 写端(如父进程写、子进程读,则父进程关读端,子进程关写端)。
  4. 读写管道 :通过read()/write()进行数据传输。
  5. 关闭管道:通信结束后,关闭剩余的读 / 写端描述符。

二、有名管道(FIFO)

1. 核心定义

有名管道(简称FIFO,First In First Out)是支持任意单机进程 (无亲缘关系也可)间通信的 IPC 机制,在文件系统中存在实体文件(有路径和名称),但文件内容仅存于内存中。

2. 核心特性

  • 继承无名管道的所有特性:半双工、不支持定位、阻塞 / 异常行为与无名管道一致。
  • 额外特性 :
    1. 文件系统可见 :通过ls命令可看到 FIFO 文件(文件类型为p)。
    2. open 函数的阻塞特性 :若只打开 FIFO 的读端或写端,open()会阻塞,直到另一端也被打开(可通过O_NONBLOCK设置非阻塞模式)。

3. 编程接口

(1)创建有名管道函数
复制代码
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
  • 功能:在指定路径下创建一个有名管道文件。
  • 参数 :
    • pathname:要创建的 FIFO 文件的路径 + 名称 (如./myfifo)。
    • mode:FIFO 文件的权限(8 进制数,如0664,最终权限会受umask影响)。
  • 返回值 :成功返回 0,失败返回 - 1(并设置errno,如文件已存在时errno为EEXIST)。

4. 编程步骤

  1. 创建 FIFO 文件 :调用mkfifo()创建有名管道(若已存在可跳过)。
  2. 打开 FIFO 文件 :进程通过open()函数打开 FIFO(指定O_RDONLY/O_WRONLY,可选O_NONBLOCK)。
  3. 读写管道 :通过read()/write()进行数据传输(与文件操作一致)。
  4. 关闭管道 :通信结束后,调用close()关闭文件描述符。
  5. 卸载 FIFO :通过unlink()或rm命令删除文件系统中的 FIFO 实体文件(可选,若后续还需使用可保留)。

三、无名管道与有名管道的核心区别

特性 无名管道(Pipe) 有名管道(FIFO)
适用进程 仅有亲缘关系进程 任意单机进程
文件系统实体 无(仅内存中存在) 有(可见的 FIFO 文件)
创建方式 pipe()函数 mkfifo()函数
打开方式 继承描述符,无需 open 需调用open()函数
相关推荐
程序员清风1 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
学长毕设1 小时前
基于SpringBoot的青少年编程学习平台系统-附源码
spring boot·学习·青少年编程
readhere2 小时前
从ZYNQ7000开发板,学会启动嵌入式Linux系统——入门学习:EBAZ4205篇目录
linux·启动·嵌入式linux·zynq7000·ebaz4205
打工仔折腾 AI3 小时前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
yyuuuzz3 小时前
跨境站点日志时区混乱的排查记录
运维·服务器·网络·云计算·aws·1024程序员节
‎ദ്ദിᵔ.˛.ᵔ₎3 小时前
关于Linux 线程局部存储的认识
linux·运维
GlobalInfo3 小时前
全球及中国风电叶片检测机器人行业研究报告(2026版):市场现状、行业前景与占有率分析
运维·网络·人工智能·机器人
数字新视界5 小时前
一体化机柜在数据中心运维中的创新应用与优势分析
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
运维行者_5 小时前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
小小de风呀5 小时前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习