《深入理解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 形式流动。

int pipe(int pipefd[2]); // pipefd[0]=read, pipefd[1]=write

特点:

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

3.2 命名管道(FIFO)

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

mkfifo /tmp/myfifo

特点:

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

3.3 内核实现

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

四、消息队列(Message Queues)

4.1 概述

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

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 内核数据结构

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

4.3 特点

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

五、信号量(Semaphores)

5.1 概述

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

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 内核结构

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

六、共享内存(Shared Memory)

6.1 概述

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

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 创建通信过程

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 对象:

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.cUNIX 域 socket 实现
include/linux/ipc_namespace.hIPC 命名空间
include/linux/shm.h共享内存头文件

十一、小结

  • Linux 提供多种 IPC 机制,各有优缺点与适用场景;
  • 信号适合简单事件通知;
  • 管道与 FIFO 适合流式数据传输;
  • 消息队列支持结构化数据传递;
  • 信号量用于同步资源控制;
  • 共享内存效率最高,但需额外同步手段;
  • 套接字最通用,跨主机通信也适用;
  • IPC 命名空间提升系统隔离性与安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88105.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88105.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/88105.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Mac 从 0 到 1 保姆级配置教程 19】- 英语学习篇-我的英语工作流分享(AI 辅助学习)

文章目录前言听力沉浸式翻译阅读Easydict配置自定义字典&#xff08;重点&#xff09;欧陆词典沙拉查词沉浸式翻译写作Eearthworm英文提问口语最后学习资料系列教程前言 本文介绍一下我日常如何学习和使用英语的工作流&#xff0c;包括一些常用好用的工具&#xff0c;好的工具…

从库函数到API接口,深挖不同语言背后的“封装”与“调用”思想

个人主页-爱因斯晨 优秀文章推荐 文章目录个人主页-爱因斯晨优秀文章推荐引言一、三种调用机制概述C语言的库函数Python 的导包机制Java 的 API 接口调用综上&#xff1a;二、它们的相同点&#xff1a;封装与调用三、不同之处**对比核心维度****细节串讲**1. **C 语言&#xf…

基于NCNN框架在Android平台实现YOLOv8目标检测模型的高效部署与实践

随着移动设备计算能力的提升&#xff0c;越来越多的深度学习模型被部署到移动端&#xff0c;以实现实时、低延迟的应用场景。YOLO系列的在目标检测任务中表现出色&#xff0c;具有精度高、速度快的优势。本文将详细介绍如何基于NCNN框架 &#xff0c;在Android平台 上高效部署Y…

华为动态路由配置

问题描述&#xff1a;针对四个路由器在不同的网段场景中&#xff0c;对四个路由器进行动态路由配置。下面以如下场景为例&#xff0c;介绍详细配置过程。配置过程&#xff1a; 1、每个路由器的接口配置IP地址 路由器AR1中每个接口配置IP地址。 sys # 进入系统视图 interface g…

分布式事务解决方案(三)

在Java分布式系统领域&#xff0c;传统强一致性方案&#xff08;如2PC、3PC&#xff09;在高并发、复杂业务场景下暴露出性能瓶颈和阻塞问题。而Saga模式与事件溯源&#xff08;Event Sourcing&#xff09;作为更具弹性和扩展性的解决方案&#xff0c;逐渐成为分布式事务处理和…

【时时三省】(C语言基础)通过指针引用数组

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省数组元素的指针一个变量有地址&#xff0c;一个数组包含若干元素&#xff0c;每个数组元素都在内存中占用存储单元&#xff0c;它们都有相应的地址。指针变量既然可以指向变量&#xff0c;当然…

【WEB】Polar靶场 21-25题 详细笔记

二十一.php very nicephp又是你 ,但是经过这么多次折磨后我感觉我已经有一点抗性了老规矩&#xff0c;先看知识点PHP 序列化是将 PHP 变量&#xff08;如对象、数组&#xff09;转换为字符串的过程&#xff0c;便于存储或传输。反序列化则是将字符串还原为原始变量。这在缓存、…

【Guava】1.0.设计虚拟机的方向

【Guava】1.0.设计虚拟机的方向虚拟机是什么&#xff1f;栈式虚拟机栈式虚拟机的优缺点题外话虚拟机是什么&#xff1f; 虚拟机&#xff08;VirtualMachine, VM&#xff09;是一种计算机程序或系统&#xff0c;它通过软件模拟物理计算机的硬件运行环境&#xff0c;使得多个操作…

[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的高校实验室资源综合管理系统,推荐!

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本高校实验室资源综合管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大…

Spring Boot:影响事务回滚的几种情况

一、Controller 捕获异常导致事务失效 需求 我们有一个用户注册服务&#xff0c;注册时需要&#xff1a; 创建用户账户分配初始积分发送注册通知 这三个操作需要在同一个事务中执行&#xff0c;任何一步失败都要回滚。 错误示例&#xff1a;Controller 捕获异常导致事务失效 Re…

如何避免分布式爬虫被目标网站封禁?

在分布式爬虫的大规模数据采集场景中&#xff0c;避免被目标网站封禁的核心逻辑是&#xff1a;通过技术手段模拟真实用户行为&#xff0c;降低爬虫行为的可识别性&#xff0c;同时建立动态适配机制应对网站反爬策略的升级。以下从请求伪装、行为控制、资源管理、反爬对抗四个维…

Maven 打包排除特定依赖的完整指南(详细方法 + 示例)

前言 在使用 Maven 构建 Java 项目时&#xff0c;我们常常需要对项目的打包过程进行精细化控制&#xff0c;尤其是希望排除某些特定的依赖库。这可能是为了减小最终构建产物的体积、避免版本冲突&#xff0c;或者仅仅是为了满足不同环境下的部署需求。 本文将详细介绍如何在 Ma…

Terraform `for_each` 精讲:优雅地自动化多域名证书验证

大家好&#xff0c;在云原生和自动化运维的世界里&#xff0c;Terraform无疑是基础设施即代码&#xff08;IaC&#xff09;领域的王者。它强大的声明式语法让我们能够轻松地描述和管理云资源。然而&#xff0c;即使是经验丰富的工程师&#xff0c;在面对某些动态场景时也可能会…

C++标准库中各种互斥锁的用法 mutex

示例 仅供参考学习 #include <mutex> #include <shared_mutex> #include <thread> #include <chrono> #include <iostream> #include <vector>// // 1. std::mutex - 基本互斥锁 // void basic_mutex_example() {std::mutex mtx;int cou…

Android Handler机制与底层原理详解

Android 的 Handler 机制是跨线程通信和异步消息处理的核心框架&#xff0c;它构成了 Android 应用响应性和事件驱动模型的基础&#xff08;如 UI 更新、后台任务协调&#xff09;。其核心思想是 “消息队列 循环处理”。 核心组件及其关系Handler (处理器): 角色: 消息的发送…

jQuery JSONP:实现跨域数据交互的利器

jQuery JSONP&#xff1a;实现跨域数据交互的利器 引言 随着互联网的发展&#xff0c;跨域数据交互的需求日益增加。在Web开发中&#xff0c;由于同源策略的限制&#xff0c;直接通过XMLHttpRequest请求跨域数据会遇到诸多问题。而JSONP&#xff08;JSON with Padding&#xff…

Redis集群和 zookeeper 实现分布式锁的优势和劣势

在分布式系统中&#xff0c;实现分布式锁是确保多个节点间互斥访问共享资源的一种常见需求。Redis 集群 和 zookeeper 都可以用来实现这一功能&#xff0c;但它们有着各自不同的优势和劣势。 CAP 理论&#xff1a; 在设计一个分布式系统时&#xff0c;一致性&#xff08;Consis…

如何备份vivo手机中的联系人?

随着vivo移动设备在全球设立7个研发中心&#xff0c;vivo正在进入更多的国家。如今&#xff0c;越来越多的人开始使用vivo手机。以vivo X100为例&#xff0c;它配备了主摄像头和多个辅助摄像头&#xff0c;提供多样化的拍摄选项&#xff0c;并搭载了最新的FunTouch OS&#xff…

python脚本编程:使用BeautifulSoup爬虫库获取热门单机游戏排行榜

BeautifulSoup是一个便捷的解析html页面元素的python库&#xff0c;此处用来写一个简单的爬虫批量抓取国内游戏资讯网站的近期热门单机游戏排行榜。 网页来源如下所示代码 from bs4 import BeautifulSoup import requests# get web page web_url "https://www.3dmgame.co…

C#配置全面详解:从传统方式到现代配置系统

C#配置全面详解&#xff1a;从传统方式到现代配置系统 在软件开发中&#xff0c;配置是指应用程序运行时可调整的参数集合&#xff0c;如数据库连接字符串、API 地址、日志级别等。将这些参数从代码中分离出来&#xff0c;便于在不修改代码的情况下调整应用行为。C# 提供了多种…