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

一、无名管道(Unnamed Pipe)

1. 核心定义

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

2. 核心特性

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

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

  3. 文件操作方式

    • 首选文件 IOopen/read/write/close),无缓冲区,效率更高;
    • 可选标准 IOfgets/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,如文件已存在时errnoEEXIST)。

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()函数
相关推荐
wljt1 小时前
HTTP和openFeign
网络·网络协议·http
汤愈韬8 小时前
ACL概述、ACL原理、基本ACL应用及配置
网络·网络协议·网络安全
微露清风8 小时前
系统性学习Linux-第二讲-基础开发工具
linux·运维·学习
不会代码的小猴9 小时前
Linux环境编程第六天笔记--system-V IPC
linux·笔记
阳光九叶草LXGZXJ9 小时前
达梦数据库-学习-48-DmDrs控制台命令(同步之Manager、CPT模块)
linux·运维·数据库·sql·学习
诸神缄默不语9 小时前
Linux命令行教程
linux
biuyyyxxx9 小时前
Python自动化办公学习笔记(一) 工具安装&教程
笔记·python·学习·自动化
小二李10 小时前
第11章 nestjs服务端开发:登录鉴权
运维·服务器
丝斯201111 小时前
AI学习笔记整理(66)——多模态大模型MOE-LLAVA
人工智能·笔记·学习
i建模11 小时前
如何在Arch Linux中重设忘记的root密码
linux·运维·服务器