【Note】《深入理解Linux内核》 第十九章:深入理解 Linux 进程通信机制

《深入理解Linux内核》 第十九章:深入理解 Linux 进程通信机制(Process Communication)

关键词:IPC、信号、管道、FIFO、消息队列、信号量、共享内存、套接字、内核对象、同步机制


一、进程通信概述

1.1 为什么需要进程通信

在 Linux 系统中,进程是资源隔离的基本单位,彼此间通常无法直接访问彼此的地址空间。因此需要一套机制,使得多个进程之间可以:

  • 交换数据
  • 同步行为
  • 发送通知
  • 共享资源

这些功能由 Linux IPC(Inter-Process Communication)子系统实现。

1.2 IPC 分类

类型 描述
信号 最基本的异步通知机制
管道/FIFO 字节流通信机制,面向数据流
消息队列 面向结构化消息,先进先出
信号量 同步与互斥,典型用于资源控制
共享内存 多进程映射同一段内存,效率最高
套接字 网络与本地通信统一抽象,支持多协议

二、信号(Signal)

2.1 概述

信号是进程间最早被引入的通信机制,本质上是一个异步事件通知。

示例信号 描述
SIGINT 中断(Ctrl+C)
SIGTERM 终止进程请求
SIGKILL 无条件终止进程(不可捕获)
SIGCHLD 子进程结束通知父进程

2.2 信号相关系统调用

  • kill(pid, sig):向指定进程或进程组发送信号;
  • signal(sig, handler):设置信号处理函数;
  • sigaction():更强大的信号控制;
  • sigprocmask():阻塞/允许某些信号;
  • sigqueue():带参数的信号发送。

2.3 内核实现

  • 每个进程结构 task_struct 中包含 sigpendingsignal 字段;
  • 信号通过 do_signal() 派发;
  • 某些信号是不可忽略/不可屏蔽的(如 SIGKILL);
  • Linux 通过实时信号(SIGRTMIN ~ SIGRTMAX)支持有序队列与附加参数。

三、管道与 FIFO

3.1 管道(pipe)

管道是最基本的 IPC 数据流机制,数据在两个进程间以 FIFO 形式流动。

c 复制代码
int pipe(int pipefd[2]); // pipefd[0]=read, pipefd[1]=write

特点:

  • 半双工(单向通信);
  • 父子进程间常见用途;
  • 基于内核中的 pipe_inode_info 结构实现;
  • 使用缓冲区环形队列实现数据传输。

3.2 命名管道(FIFO)

可跨进程、不限于亲缘关系:

bash 复制代码
mkfifo /tmp/myfifo

特点:

  • 是一种特殊文件;
  • 可在 shell 中使用 < /tmp/myfifo> /tmp/myfifo

3.3 内核实现

  • 管道是内核中一种特殊的字符设备;
  • 每个 pipe 被表示为一个 inode;
  • 内核用 struct pipe_inode_info 管理缓冲区、读写端等。

四、消息队列(Message Queues)

4.1 概述

消息队列允许进程以"消息"为单位进行通信,每条消息是结构化数据(类型 + 数据内容)。

c 复制代码
int msgget(key_t key, int msgflg);
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

4.2 内核数据结构

c 复制代码
struct msg_queue {
    struct list_head q_messages;
    ...
};
  • 所有消息链入 q_messages
  • 支持按类型匹配接收;
  • 消息大小有限制(msgmax)。

4.3 特点

  • 支持异步发送、同步接收;
  • 按优先级接收;
  • 属于 System V IPC 之一;
  • 支持权限与 quota 控制。

五、信号量(Semaphores)

5.1 概述

信号量提供一种同步机制,用于控制多个进程对共享资源的访问,支持阻塞和非阻塞操作。

c 复制代码
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, size_t nsops);
  • 每个信号量集合由 semid 索引;
  • semop() 支持加锁/解锁操作(P/V操作);
  • 使用计数表示资源状态。

5.2 内核结构

c 复制代码
struct sem_array {
    struct sem *sem_base;
    ...
};
  • Linux 信号量集支持原子操作;
  • 支持 undo 机制,在进程终止时自动释放资源;
  • 属于 System V IPC 范畴,现代内核中逐渐被 futex 和 pthread 替代。

六、共享内存(Shared Memory)

6.1 概述

多个进程将一段物理内存映射到各自虚拟地址空间,实现高效通信。

c 复制代码
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);

特点:

  • 速度最快的 IPC;
  • 通常配合信号量/互斥锁使用;
  • 属于 System V IPC;

6.2 内核实现

  • 使用 shmid_kernel 描述共享段;
  • 实质上是内核为各进程映射同一段物理页;
  • 页表项被多个进程共享;
  • 写时复制(COW)策略在此无效。

七、套接字通信(Socket)

7.1 套接字种类

类型 描述
UNIX 域套接字 仅限本机通信,文件系统路径寻址
INET 套接字 网络通信,使用 IP 与端口
STREAM 面向连接,类似 TCP
DGRAM 无连接,类似 UDP

7.2 创建通信过程

c 复制代码
int socket(int domain, int type, int protocol);
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • socket 通信是最通用的进程通信方式;
  • 在内核中通过 sock 结构表示;
  • 数据缓冲使用 sk_buff 结构管理。

八、Linux IPC 统一接口

Linux 提供 /proc/sysvipc/ 系统接口与 ipcs 工具来统一查看 IPC 对象:

bash 复制代码
ipcs -m   # 共享内存
ipcs -q   # 消息队列
ipcs -s   # 信号量

可以使用 ipcrm 删除对象。


九、IPC 命名空间与隔离(Namespace)

9.1 IPC Namespace

每个 IPC 对象(shm、sem、msg)都可以在命名空间中隔离,容器技术(如 Docker)广泛使用。

  • 创建 IPC namespace:unshare --ipc
  • 每个命名空间有独立的 IPC 资源空间;
  • 安全、稳定、互不干扰。

十、内核源码参考路径

文件路径 作用描述
kernel/signal.c 信号实现与分发
ipc/msg.c 消息队列实现
ipc/sem.c 信号量实现
ipc/shm.c 共享内存实现
fs/pipe.c 管道与 FIFO 实现
net/unix/af_unix.c UNIX 域 socket 实现
include/linux/ipc_namespace.h IPC 命名空间
include/linux/shm.h 共享内存头文件

十一、小结

  • Linux 提供多种 IPC 机制,各有优缺点与适用场景;
  • 信号适合简单事件通知;
  • 管道与 FIFO 适合流式数据传输;
  • 消息队列支持结构化数据传递;
  • 信号量用于同步资源控制;
  • 共享内存效率最高,但需额外同步手段;
  • 套接字最通用,跨主机通信也适用;
  • IPC 命名空间提升系统隔离性与安全性。
相关推荐
鹏仔先生3 小时前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
大树886 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质7 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush47 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5207 小时前
Linux 11 动态监控指令top
linux
Inhand陈工8 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智8 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
云水一下8 小时前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
不会C语言的男孩8 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言