news 2026/4/29 23:45:24

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/4/25 14:30:17

电商系统中的CountDownLatch实战:订单多服务并行校验

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 构建一个电商订单校验系统的模拟场景&#xff1a;1) 使用CountDownLatch协调库存服务、支付服务和风控服务的并行校验&#xff1b;2) 每个服务用独立线程实现&#xff0c;校验耗时随…

作者头像 李华
网站建设 2026/4/23 0:27:02

守护进程(daemon)创建的通用步骤

一、什么是“现代守护进程” 现代守护进程的核心特征不是“一定要 double fork”,而是: 与控制终端彻底脱离 不再属于任何前台进程组 能在用户退出 / 终端关闭后继续运行 具备可预测的信号、文件描述符和运行环境 能被 init / systemd 正确管理(现代系统) 二、经典守…

作者头像 李华
网站建设 2026/4/23 11:31:46

草履虫也能学会的强化学习系列(7)

更一期草履虫强化学习系列&#xff08;书稿&#xff09;1.2.3 蒙特卡罗树搜索算法原理在强化学习&#xff08;Reinforcement Learning, RL&#xff09;的语境下&#xff0c;蒙特卡洛&#xff08;Monte Carlo, MC&#xff09;方法通常被归类为无模型&#xff08;Model-Free&…

作者头像 李华
网站建设 2026/4/29 20:32:50

力扣983最低票价 - 一维DP - 值域爬楼梯与二分优化

983. 最低票价 这题可以看成「爬楼梯」题目的变种。 有两种思考角度&#xff0c;每种角度有两种写法。 角度一 我们从旅游的第一天 iii 开始思考&#xff0c;nnn 为旅行的最后一天&#xff0c;寻找子问题&#xff0c;分类讨论&#xff1a; 在第 iii 天购买 111 天的车票&…

作者头像 李华