news 2026/3/19 10:37:47

Linux系统编程——IPC进程间通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux系统编程——IPC进程间通信

目录

一、Linux IPC 的核心种类

1.古老的通信方式

2.IPC 对象通信(system v 标准)

3.socket 通信

二、无名管道(匿名管道)

1. 核心特性

2.读写行为规则

3.编程顺序

4.核心函数:pipe

5.示例代码:父子进程通过无名管道通信

三、有名管道

1.核心特性

2.编程顺序

3.核心函数:mkfifo

4.示例代码:两个无亲缘进程通过 FIFO 通信

四、无名管道与有名管道核心对比

五、总结


一、Linux IPC 的核心种类

1.古老的通信方式

是 Linux 早期的基础 IPC 实现,包括:

  • 无名管道
  • 有名管道
  • 信号

2.IPC 对象通信(system v 标准)

基于内核对象的通信方式,常用的有:

  • 消息队列(使用相对较少,这里不讨论)
  • 共享内存
  • 信号量集

3.socket 通信

支持跨主机的网络级通信,核心场景是:

  • 网络通信

注:管道的底层实现是队列,数据遵循 “先进先出” 规则。

二、无名管道(匿名管道)

无名管道对应 pipe,是仅支持亲缘关系进程(如父子、兄弟进程)通信的方式。

1. 核心特性

  • 仅能给亲缘关系进程通信;
  • 半双工工作模式(实际编程按单工使用);
  • 是特殊文件,不支持定位操作(lseek 对管道文件描述符 / 文件指针无效);
  • 依赖文件 IO / 标准 IO 操作。

2.读写行为规则

管道的读写逻辑受缓冲区(默认 64K)和两端状态影响:

  1. 读端存在时,写端持续写超 64K 会阻塞(写得太快);
  2. 写端存在时,读端读空管道会阻塞(读得太快);
  3. 读端关闭后,写端写管道会导致写进程崩溃(管道破裂);
  4. 写端关闭后,读端读完管道内容,read 会返回 0,标志进程间通信结束。

3.编程顺序

创建管道 → fork子进程 → 读写管道 → 关闭管道

4.核心函数:pipe

int pipe(int pipefd[2]);
  • 功能:创建并打开一个无名管道;
  • 参数:pipefd[0] 是无名管道的固定读端,pipefd[1] 是固定写端;
  • 返回值:成功返回 0,失败返回 - 1。

5.示例代码:父子进程通过无名管道通信

#include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/wait.h> int main() { int pipe_fd[2]; pid_t pid; char read_buf[1024] = {0}; const char *write_data = "Hello from parent (pipe)!"; // 1. 创建无名管道 if (pipe(pipe_fd) == -1) { perror("pipe create failed"); return -1; } // 2. fork创建子进程(建立亲缘关系) pid = fork(); if (pid == -1) { perror("fork failed"); return -1; } // 3. 父进程:关闭读端,向管道写数据 if (pid > 0) { close(pipe_fd[0]); // 父进程仅写,关闭读端 write(pipe_fd[1], write_data, strlen(write_data)); close(pipe_fd[1]); // 写完关闭写端 wait(NULL); // 等待子进程执行完毕 } // 4. 子进程:关闭写端,从管道读数据 else { close(pipe_fd[1]); // 子进程仅读,关闭写端 read(pipe_fd[0], read_buf, sizeof(read_buf)); printf("Child read: %s\n", read_buf); close(pipe_fd[0]); // 读完关闭读端 } return 0; }

三、有名管道

有名管道对应 fifo,突破了亲缘关系限制,支持任意单机进程通信(只要知道管道的文件路径),且在文件系统中可见(有明确的路径名称)。

1.核心特性

  • 可给任意单机进程通信,文件系统中可见(有路径);
  • 基础特性与无名管道一致(半双工、特殊文件、不支持定位等);
  • 额外特性:若管道一端未打开,open 函数会默认阻塞。

2.编程顺序

创建有名管道 → 打开有名管道 → 读写管道 → 关闭管道 → 卸载有名管道

3.核心函数:mkfifo

int mkfifo(const char *pathname, mode_t mode);
  • 功能:在指定路径下创建一个有权限的有名管道文件;
  • 参数:pathname 是有名管道的路径 + 名称,mode 是 8 进制的文件权限(如0666);
  • 返回值:成功返回 0,失败返回 - 1。

4.示例代码:两个无亲缘进程通过 FIFO 通信

  • 写进程(fifo_write.c):
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #define FIFO_PATH "/tmp/my_fifo" int main() { // 1. 创建FIFO文件(已存在则忽略) if (mkfifo(FIFO_PATH, 0666) == -1) { perror("mkfifo failed (ignore if exist)"); } // 2. 打开FIFO文件(写模式) int fd = open(FIFO_PATH, O_WRONLY); if (fd == -1) { perror("open fifo failed"); return -1; } // 3. 向FIFO写数据 const char *msg = "Hello from FIFO write process!"; write(fd, msg, strlen(msg)); printf("Write to FIFO: %s\n", msg); // 4. 关闭并卸载FIFO close(fd); unlink(FIFO_PATH); return 0; }
  • 读进程(fifo_read.c):
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <string.h> #define FIFO_PATH "/tmp/my_fifo" int main() { char buf[1024] = {0}; // 1. 打开FIFO文件(读模式,阻塞等待写端) int fd = open(FIFO_PATH, O_RDONLY); if (fd == -1) { perror("open fifo failed"); return -1; } // 2. 从FIFO读数据 read(fd, buf, sizeof(buf)); printf("Read from FIFO: %s\n", buf); // 3. 关闭FIFO close(fd); return 0; }

四、无名管道与有名管道核心对比

对比维度无名管道(pipe)有名管道(FIFO)
通信范围仅亲缘关系进程任意单机进程
文件系统可见性不可见(内核维护)可见(有路径的特殊文件)
打开特性fork 后继承文件描述符一端未打开时 open 默认阻塞
生命周期随进程退出自动释放需手动 unlink 删除
创建方式pipe () 函数mkfifo () 函数

五、总结

  1. 管道是 Linux 最基础的 IPC 机制,核心分为无名管道(pipe)和有名管道(FIFO)两类,均为半双工、基于队列的特殊文件;
  2. 无名管道仅支持亲缘进程通信,无需手动清理;有名管道支持任意单机进程通信,需手动创建 / 删除;
  3. 管道读写需遵循核心规则,尤其注意 “读 / 写端关闭” 后的行为,避免进程崩溃或数据异常。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/15 23:53:12

错过后悔一年!2024最值得收藏的智能家居能源优化框架发布

第一章&#xff1a;智能家居 Agent 的能源管理在现代智能家居系统中&#xff0c;智能 Agent 扮演着核心调度角色&#xff0c;尤其在能源管理方面发挥着关键作用。通过实时采集家庭用电设备的运行状态与能耗数据&#xff0c;Agent 能够动态优化能源分配&#xff0c;降低整体功耗…

作者头像 李华
网站建设 2026/3/15 13:10:08

快速验证:用AI工具10分钟搭建wx-open-launch-app原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速生成一个wx-open-launch-app的功能原型&#xff0c;包含基本界面和跳转逻辑。要求代码轻量&#xff0c;能立即运行测试。界面只需包含必要元素&#xff0c;重点展示功能可行性。…

作者头像 李华
网站建设 2026/3/15 23:53:13

医疗康复Agent如何实现动态方案调整?揭秘AI驱动精准康复的3个关键步骤

第一章&#xff1a;医疗康复Agent的方案调整机制概述在智能医疗系统中&#xff0c;医疗康复Agent作为核心决策组件&#xff0c;负责根据患者实时健康数据动态调整治疗与康复方案。其调整机制依赖于多源数据融合、临床知识图谱推理以及个性化学习模型&#xff0c;确保推荐策略既…

作者头像 李华
网站建设 2026/3/15 16:56:13

首次公开:跨国药企内部使用的Agent实验设计模板(含数据建模流程)

第一章&#xff1a;生物制药Agent实验设计的核心理念在现代生物制药研发中&#xff0c;Agent&#xff08;智能体&#xff09;驱动的实验设计正逐步成为加速药物发现与优化的关键范式。这类系统通过模拟生物分子间的相互作用、预测药代动力学特性&#xff0c;并自主迭代实验方案…

作者头像 李华
网站建设 2026/3/17 7:02:38

深入理解Ansible变量:灵活配置自动化任务的关键

引言 在Ansible自动化运维中&#xff0c;变量是构建灵活、可复用Playbook的核心组件。它们就像编程语言中的变量一样&#xff0c;允许我们动态地存储和引用数据&#xff0c;实现"一次编写&#xff0c;多处使用"的配置管理理念。本文将全面解析Ansible变量的使用方法…

作者头像 李华
网站建设 2026/3/19 3:51:10

Day 42 Dataset 和 Dataloader 类

浙大疏锦行 一、核心定位 类核心角色核心作用Dataset「数据容器」/「数据加工厂」定义单条数据的读取、预处理逻辑&#xff08;如从 CSV 读一行、编码、填充、标准化&#xff09;&#xff0c;支持按索引取数DataLoader「数据搬运工」/「批量调度器」封装 Dataset&#xff0c;…

作者头像 李华