news 2026/9/1 6:16:17

Linux 进程间通信(IPC)详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 进程间通信(IPC)详解

1. 进程间通信的方法

进程间通信(IPC,Inter-Process Communication)是操作系统中不同进程之间交换数据与信息的机制。Linux 下常用的进程间通信方式包括:

  1. 管道:包括无名管道和有名管道,用于有亲缘关系或任意进程之间的字节流传输。
  2. 信号:内核与应用层之间的一种异步通信机制,用于通知进程发生了某种事件。
  3. 消息队列:以消息为单位进行数据交换,支持按类型读取。
  4. 共享内存:多个进程直接映射同一块物理内存,读写效率最高。
  5. 信号灯(信号量):用于进程间的同步与互斥,控制对共享资源的访问。

2. 管道

2.1 无名管道

无名管道只能用于具有亲缘关系的进程间通信,例如父子进程之间。它由内核提供一段缓冲区,通过文件描述符进行读写。

函数接口:pipe
int pipe(int pipefd[2]); 功能:创建一段用于进程间通信的内核缓存区 参数:pipefd[0]:读文件描述符 pipefd[1]:写文件描述符 返回值:成功返回 0,失败返回 -1

2.2 管道特性

  • 管道中有写端
    • 管道中有数据:直接读出。
    • 管道中没有数据:阻塞等待,直到数据写入后再读出。
  • 管道中没有写端
    • 管道中有数据:直接读出。
    • 管道中没有数据:直接结束,不需要阻塞等待。
  • 管道中有读端
    • 管道没有写满(64K):直接写入数据。
    • 管道写满:需要等数据读出后才能继续写入。
  • 管道中没有读端:写入数据会产生管道破裂的错误,使进程直接退出。

2.3 有名管道

有名管道可以用于任意两个进程之间的通信。读写两端必须同时加入才能继续向下执行;如果只有读写一端,则会阻塞等待,直到另一端加入。

函数接口:mkfifo
int mkfifo(const char *pathname, mode_t mode); 功能:创建一个有名管道 参数:pathname:有名管道的路径 mode:权限 返回值:成功返回 0,失败返回 -1
编程练习:实现 read.c 和 write.c 聊天功能

编写两个程序 read.c 和 write.c:

  • write.c 负责从终端接收内容,发送给 read.c。
  • read.c 将接收内容打印后,再从终端接收内容发送给 write.c。
  • write.c 打印后重复执行如上内容,实现 read.c 和 write.c 的聊天功能。

3. 信号

3.1 信号概述

信号是内核层与应用层通信的一种机制。应用层收到信号后的处理方式有三种:

  1. 缺省:按照默认方式处理信号。
  2. 忽略:不处理信号。
  3. 捕捉:按照指定的方式处理信号。

3.2 常见信号种类

信号触发方式说明
SIGINT从键盘输入 ctrl + c中断信号
SIGQUIT从键盘输入 ctrl + \退出信号
SIGKILLkill -9不能被忽略和捕捉
SIGSEGV非法内存访问段错误
SIGPIPE管道破裂写无读端管道时触发
SIGALRM定时时间达到由 alarm 触发
SIGCHLD子进程结束通知父进程回收
SIGCONT继续执行恢复暂停进程
SIGSTOP暂停信号不能被忽略和捕捉
SIGTSTP从键盘输入 ctrl + z挂起信号
SIGIO异步 IO异步 IO 信号

注意:9 号(SIGKILL)和 19 号(SIGSTOP)信号不能被忽略和捕捉。

3.3 函数接口

signal
typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 功能:改变信号的处理方式 参数:signum:信号的编号 handler: SIG_IGN:忽略信号 SIG_DFL:缺省(默认方式)处理信号 捕捉:传入信号的处理方式 返回值:成功返回上一次注册的信号对应的处理方式,失败返回 SIG_ERR
pause
int pause(void); 功能:让进程睡眠
alarm
unsigned int alarm(unsigned int seconds); 功能:隔 seconds 秒后给调用进程发送 SIGALRM 信号

3.4 信号编号速查表

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX

4. 信号量(信号灯)

信号量用于进程间的同步与互斥,通过资源计数控制对共享资源的访问。

int sem_post(sem_t *sem); 功能:释放资源,让资源数 +1 参数:sem:信号量空间首地址 返回值:成功返回 0,失败返回 -1

5. 消息队列

5.1 IPC 对象

IPC 对象是内核中的一种内存文件,每个 IPC 对象可以创建一个消息队列、一个共享内存和一个信号灯。

5.2 IPC 对象查看命令

ipcs -q/m/s ipcrm -Q/M/S IPC对象名称(Key值) ipcrm -q/m/s 消息队列ID号/共享内存ID号/信号量数组ID号

5.3 消息队列操作方式

  1. 创建 IPC 对象的名称(ftok)
  2. 创建消息队列(msgget)
  3. 消息队列发送消息(msgsnd)
  4. 消息队列接收消息(msgrcv)
  5. 消息队列控制(msgctl)

5.4 函数接口

ftok
key_t ftok(const char *pathname, int proj_id); 功能:根据目录名和 8 位项目 ID 生成 key 值 参数:pathname:目录名 proj_id:项目 ID 返回值:成功返回 key_t 类型的 IPC 对象名称,失败返回 -1
msgget
int msgget(key_t key, int msgflg); 功能:根据 key 值创建消息队列 参数:key:IPC 对象名称 msgflg:IPC_CREAT 不存在创建,IPC_EXCL 存在报错 返回值:成功返回消息队列 ID,失败返回 -1
msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 功能:向消息队列中发送消息 参数:msqid:消息队列 ID 号 msgp:发送消息的空间的首地址 msgsz:发送消息内容的大小 msgflg:消息属性,默认 0 返回值:成功返回 0,失败返回 -1
msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg); 功能:从消息队列中接收消息 参数:msqid:消息队列的 ID 号 msgp:存放消息空间的首地址 msgsz:最多接收数据的字节数 msgtyp:接收消息的 ID 号 msgflg:默认为 0 返回值:成功返回实际接收字节数,失败返回 -1
msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf); 功能:向消息队列发送命令 参数:msqid:消息队列 ID 号 cmd:IPC_STAT 获得消息队列状态信息 IPC_SET 修改消息队列权限 IPC_RMID 删除消息队列 返回值:成功返回 0,失败返回 -1

5.5 编程练习:实现 send.c 和 recv.c

编写 send.c 和 recv.c:

  • send.c 负责从终端接收字符串,发送到消息队列。
  • recv.c 负责从消息队列接收内容并打印在终端。

6. 共享内存

6.1 共享内存概述

共享内存是进程间通信最高效的形式。

6.2 共享内存操作步骤

  1. 创建 IPC 对象名称(键值)(ftok)
  2. 创建共享内存(shmget)
  3. 将进程地址映射到共享内存中(shmat)
  4. 使用共享内存空间
  5. 解除映射(shmdt)
  6. 销毁共享内存空间(shmctl)

6.3 函数接口

shmget
int shmget(key_t key, size_t size, int shmflg); 功能:创建一个共享内存 参数:key:IPC 对象名称 size:共享内存的大小 shmflg:IPC_CREAT 不存在就创建,IPC_EXCL 存在就报错 返回值:成功返回共享内存 ID,失败返回 -1
shmat
void *shmat(int shmid, const void *shmaddr, int shmflg); 功能:将进程空间地址映射到共享内存中 参数:shmid:共享内存 ID 号 shmaddr:NULL 选择默认的合适地址映射 shmflg:0 返回值:成功返回映射到共享空间中的地址,失败返回 -1
shmdt
int shmdt(const void *shmaddr); 功能:解除映射 参数:shmaddr:映射到共享内存空间的首地址 返回值:成功返回 0,失败返回 -1
shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf); 功能:向共享内存发送命令 参数:shmid:共享内存 ID 号 cmd:IPC_STAT 获得属性 IPC_SET 设置权限 IPC_RMID 删除共享内存 返回值:成功返回 0,失败返回 -1

7. 有名信号量

7.1 函数接口

semget
int semget(key_t key, int nsems, int semflg); 功能:创建信号量数组 参数:key:IPC 对象名称 nsems:信号量的个数 semflg:IPC_CREAT 不存在创建,IPC_EXCL 存在报错 返回值:成功返回信号量数组的 ID 号,失败返回 -1
semctl
int semctl(int semid, int semnum, int cmd, ...); 功能:对信号量数组进行控制操作 参数:semid:信号量数组 ID 号 semnum:信号量编号 cmd:IPC_STAT 获得属性 IPC_SET 设置权限 IPC_RMID 删除信号量数组 返回值:成功返回 0,失败返回 -1
semop
int semop(int semid, struct sembuf *sops, size_t nsops); 功能:对信号量进行 P/V 操作 参数:semid:信号量数组 ID 号 sops:操作结构体数组 nsops:操作个数 返回值:成功返回 0,失败返回 -1
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 6:15:02

Anthropic MHS标准解读:重塑Agent工具调用与上下文管理

近几个月,AI 领域的竞争已经从前端模型能力,悄悄转移到了更底层的地方:上下文怎么组织、工具怎么调用、模型与外部系统之间怎么约定交互格式。如果你一直在用 Claude 的 API,或者正在做 Agent 类应用,大概率会遇到一个…

作者头像 李华
网站建设 2026/9/1 6:14:24

外汇历史数据清洗与标准化:构建可复用的数据文件管线

简介:这是一份带配套程序的外汇数据文件包,主要面向需要研究汇率数据、量化策略或本地运行演示程序的交易学习者和开发人员。包内不仅提供 FXDB 格式的外汇数据文件,还包含 MasterSignal 主程序、System.Data.SQLite 等动态库和 JSON 配置文件…

作者头像 李华
网站建设 2026/9/1 6:14:08

TinyPerson数据集COCO转YOLO格式完整教程与训练避坑指南

简介:该数据集面向目标检测、人群检测及小目标检测方向的开发者与研究者,由TinyPerson图像整理而成,共包含1532张带标注样本,标注格式覆盖VOC xml与YOLO txt两种主流类型,其中YOLO txt已划分好训练、验证、测试集&…

作者头像 李华
网站建设 2026/9/1 6:13:59

基于C#的在线SPC质量监控系统开发实战

简介:本资源是一套基于统计过程控制(SPC)理论开发的在线质量监控系统C#源码,面向计算机、自动化及相关专业本科生毕业设计与课程实践需求,解决制造业场景下生产数据实时采集、过程稳定性分析与异常预警等核心问题。压缩…

作者头像 李华
网站建设 2026/9/1 6:11:06

EPLAN Electric P8实战:锂电池生产线电气设计全流程解析

大家好,我是专注于工业电气设计领域的技术博主。最近在参与一个锂电池PACK(电池包)生产线的电气设计项目时,深刻体会到一套高效、规范的电气设计软件对于项目质量和效率的决定性影响。面对复杂的工艺流程、海量的设备信号和严格的…

作者头像 李华