Linux编程-IPC通信 一、Signal 信号信号 IPC核心原理信号是异步短消息内核作为中间人给进程发送一个整型编号SIGUSR1、SIGUSR2 常用自定义信号只能传递信号编号不能携带大量数据信号是Linux 中一种异步通信机制内核发给进程的简短通知告知进程发生了某个事件。 进程收到信号有三种处理方式默认动作SIG_DFL系统预设终止、忽略、停止、继续忽略SIG_IGN收到不做处理SIGKILL、SIGSTOP 不能忽略自定义信号处理函数signal /sigaction 注册回调Linux 标准信号大全1~31 传统不可靠信号POSIX 标准默认动作缩写说明Term终止进程Core终止 生成 core dump 崩溃转储文件Ign默认忽略Stop暂停进程Cont恢复已暂停进程 ⚠️SIGKILL (9)、SIGSTOP (19) 不可捕获、不可阻塞、不可忽略编号信号名默认动作说明1SIGHUPTerm终端挂起 / 控制进程退出常用于守护进程重载配置2SIGINTTermCtrlC终端请求中断进程3SIGQUITCoreCtrl\退出并生成 core 文件4SIGILLCore非法 CPU 指令执行5SIGTRAPCore调试断点、陷阱指令gdb 使用6SIGABRTCoreabort () 主动异常终止程序7SIGBUSCore总线错误非法内存访问、内存对齐异常8SIGFPECore算术异常除 0、浮点溢出等9SIGKILLTermkill -9强制杀死进程无法拦截10SIGUSR1Term用户自定义信号 1业务自由使用11SIGSEGVCore段错误非法内存读写空指针、越界12SIGUSR2Term用户自定义信号 2业务自由使用13SIGPIPETerm管道破裂向无读端的管道 /socket 写入数据14SIGALRMTermalarm () 定时器到期15SIGTERMTermkill 默认信号优雅关闭进程推荐程序正常退出16SIGSTKFLTTerm协处理器栈错误Linux 基本废弃不用17SIGCHLDIgn子进程终止 / 暂停通知父进程回收僵尸进程核心信号18SIGCONTCont恢复被 SIGSTOP/SIGTSTP 暂停的进程19SIGSTOPStop强制暂停进程无法拦截20SIGTSTPStopCtrlZ终端交互式暂停进程21SIGTTINStop后台进程读取终端输入22SIGTTOUStop后台进程向终端输出23SIGURGIgnsocket 带外紧急数据到达24SIGXCPUCore超出进程 CPU 资源上限25SIGXFSZCore超出文件大小资源上限26SIGVTALRMTermsetitimer 虚拟定时器到期仅统计用户态 CPU 时间27SIGPROFTerm剖析定时器到期用户 内核 CPU 时间28SIGWINCHIgn终端窗口大小改变resize 窗口触发29SIGIO / SIGPOLLTermIO 就绪事件轮询可用30SIGPWRTerm电源故障、断电预警31SIGSYSCore非法系统调用seccomp 安全机制常用signal () 函数注册信号signum信号编号SIGINT、SIGCHLD…handler处理函数填SIG_DFL使用默认SIG_IGN忽略也可自定义处理函数sighandler返回值成功返回旧处理函数指针失败返回SIG_ERR#include signal.h // 函数原型 //自定义处理函数形式为函数指针本质是回调函数 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);常用标准信号信号名编号触发场景默认行为SIGINT2CtrlC 终端中断终止进程SIGKILL9kill -9 强制杀死终止不可捕获 / 忽略SIGSEGV11段错误非法内存访问终止 coreSIGCHLD17子进程退出 / 停止通知父进程忽略SIGSTOP19CtrlZ 暂停进程暂停不可捕获SIGCONT18恢复被暂停进程继续运行SIGALRM14alarm () 定时器到期终止kill () 向进程发信号int kill(pid_t pid, int sig); pid某个进程的pid编号 sig需要发送的信号类型哪一种信号的宏定义名字一般是这么写的raise () 给自己发信号int raise(int sig); 等价于 kill(getpid(), sig);pause () 阻塞进程直到收到信号并执行 handler阻塞等待接收信号当前进程接收到任何一个信号都会有执行对应的handler如果没注册就执行系统默认的操作具体执行的对应操作详见第一个表格1-31号信号的信息详解。收到信号处理完后 pause 返回 - 1。int pause(void);alarm()定时产生信号设置定时器seconds 秒之后内核向当前进程发送 SIGALRM (14) 信号,多次调用 alarm会覆盖上一次定时器,sleep () 内部很多实现依赖 alarm SIGALRM二者混用会互相干扰unsigned int alarm(unsigned int seconds); // seconds秒后发送SIGALRM二、System V 共享内存Shared Memory核心原理在内核中开辟一块物理内存区域多个进程通过虚拟地址映射到同一块物理内存不发生数据拷贝速度是所有 IPC 里最快的。缺点本身不带同步互斥多进程并发读写会产生竞态必须搭配信号量 / 信号 / 互斥锁使用。System V IPC 键值keykey 是key_t类型的整数键值作为 System V IPC 对象共享内存、消息队列、信号量的全局逻辑名称用于多进程定位同一个内核 IPC 对象存放在内核struct ipc_perm权限结构体中多个独立进程无父子继承关系想要访问同一个共享内存 / 消息队列 / 信号量集约定使用相同 key内核根据 key 定位对应的 IPC 资源。#include sys/types.h #include sys/ipc.h key_t ftok(const char *pathname, int proj_id); 返回值成功 返回唯一键值 失败 -1pathname必须是存在、可访问的文件路径普通文件 / 目录都行ftok 内部读取这个文件的stat 信息st_dev (设备号)、st_ino (inode 号)⚠️ 文件不能删除重建删了再新建inode 大概率改变 → ftok 算出 key 变了proj_idproject id仅使用该 int 的低 8 位0~255非 0 常用一般传字符常量如a、b相同 path不同 proj_id → 不同 key用人话说就是两个参数组合起来可以计算得到一个固定的值这就是一个key通过这个key就可以在不同的进程中访问到同一块内核的内存地址。使用SystemV共享内存的流程步骤生成 keyftok / 直接指定 / IPC_PRIVATEshmget创建 / 获取共享内存段得到 shmidshmat将共享内存挂载映射到进程虚拟地址空间得到可用指针读写这块内存和普通内存指针用法一致shmdt卸载共享内存断开映射不删除内核段shmctlIPC_RMID 删除内核中的共享内存段最后一个进程 detach 后才真正销毁fotok生成keykey是一个32位的值#includestdio.h #includestdlib.h #includesys/types.h #includesys/ipc.h int main(int argc, const char *argv[]) { key_t key ftok(/,a); if(key 0) { perror(ftok fail); return -1; } printf(key %#x\n,key); return 0; }shmget创建共享内存段并获得该段的shmid号int shmget(key_t key, size_t size, int shmflg); 功能 使用唯一键值key向内核提出共享内存使用申请 参数 key 唯一键值 size 要申请的共享内存大小 shmflg 申请的共享内存访问权限八进制表示 如果是第一个申请则用IPC_CREAT 如果要检测是否存在用IPC_EXCL 返回值 成功 返回共享内存id一般用shmid表示 失败 -1 int shmid shmget(key,1024,IPC_CREAT|0666); if(shmid 0) { perror(shmget fail); return -1; }shmat将进程中的共享内存映射到内核空间里的共享内存地址void *shmat(int shmid, const void *shmaddr, int shmflg); 功能将指定shmid对应的共享内存映射到本地内存。 参数shmid 要映射的本地内存 shmaddr 本地可用的地址如果不确定则用NULL表示 由系统自动分配。 shmflg 0 , 表示读写 SHM_RDONLY, 只读 返回值 成功 返回映射的地址一般等于shmaddr 失败 (void*)-1int *p shmat(shmid,NULL,0);映射挂载后可以直接使用命令行查看当前共享内存段的信息映射成功后会返回void *类型的空类型指针一般可以自定义类型指针进行接受并使用该地址使用的时候需要对地址进行强转类型。shmdt撤销映射如需要取消映射也可把这个地址使用shmdt进行解映射但要注意该函数的参数同样是void *类型的在传参的时候需要进行强转。int shmdt(const void *shmaddr); 功能将本地内存与共享内存断开映射关系。 参数 shmaddr 要断开的映射地址。 //shmaddr 参数必须是前面shmat 函数返回的地址 返回值 成功 0 失败 -1shmctl对象使用完成后进行销毁动作共享内存只是一块公共内存内核不会保护并发读写。 多个进程同时读写同一块区域会产生竞态条件、数据错乱。因此在使用的时候最好搭配同步互斥或信号量使用。int shmctl(int shmid, int cmd, struct shmid_ds *buf); 功能 修改共享内存属性也可以删除指定的共享内存对象。 参数 shmid 要删除的共享内存对象 cmd PC_RMID 删除对象的宏 buff NULL 表示只删除对象。 返回值 成功 0 失败 -1共享内存 a.key -- ftok b.shmid -- shmget c.映射 -- shmat d.解除 -- shmdt e.销毁 -- shmctl共享内存System V vs pipe匿名管道 vs FIFO有名管道对比项pipe匿名管道FIFO有名管道System V 共享内存进程关系必须有亲缘关系父子任意无亲缘进程任意无亲缘进程通信方向单向半双工默认单向可双开读写实现双向双向随意读写数据传输方式两次拷贝用户缓冲区 → 内核 pipe 缓冲区 → 另一进程用户缓冲区同 pipe内核缓冲区中转拷贝无数据拷贝多进程映射同一块物理内存直接访问同步机制自带阻塞读写同步内核实现自带阻塞读写同步无任何同步需要手动信号量 / 消息队列互斥数据生命周期管道关闭、所有 fd 释放后内核销毁所有读写端关闭后内核释放磁盘仅存 inode不存数据独立于进程必须 shctl IPC_RMID 才删除否则常驻内核数据读写特点流式字节流无边界需要自己分包流式字节流无边界任意读写支持随机访问像数组内核资源文件描述符文件描述符文件系统实体IPC 对象ipcs 查看最大容量内核 pipe 缓冲区默认几 KB内核缓冲区限制可配置支持大块内存MB/GB 级别适用场景父子进程简单少量单向通信不相关进程少量流式传输大数据、高频交互进程通信销毁方式close fd 自动释放所有进程 close 自动释放必须 shmctl (IPC_RMID)否则内核残留

相关新闻

最新新闻

论文AI率过高怎么办?2026年12款免费降AI率工具实测指南

论文AI率过高怎么办?2026年12款免费降AI率工具实测指南

现在毕业论文答辩前,“AI率超标”已经彻底取代“查重率过高”,成了同学们的头号难题!不少同学只是用AI润色了摘要和结论,AI率直接飙升到离谱,纯手动修改根本不管用——这说明AIGC检测系统抓的不是个别词语,…

2026/8/24 0:02:09
Marketch:从Sketch画板直接量取CSS

Marketch:从Sketch画板直接量取CSS

Marketch:从Sketch画板直接量取CSS 【免费下载链接】marketch Marketch is a Sketch 3 plug-in for automatically generating html page that can measure and get CSS styles on it. 项目地址: https://gitcode.com/gh_mirrors/ma/marketch 设计稿交付还在…

2026/8/24 0:02:09
如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南

如何在ThinkPad X390上安装macOS:OpenCore EFI完整指南 【免费下载链接】ThinkpadX390-Opencore-EFI macOS Catalina & Big Sur & Monterey on ThinkPad X390 (Hackintosh) 项目地址: https://gitcode.com/gh_mirrors/th/ThinkpadX390-Opencore-EFI …

2026/8/24 0:02:09
WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化

WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化

WechatHook 终极指南:5大核心能力详解,3分钟看懂微信自动化 【免费下载链接】WechatHook Enjoy hooking wechat by Xposed....Accessibility...and so on... 项目地址: https://gitcode.com/gh_mirrors/we/WechatHook WechatHook 是一个基于 Xpos…

2026/8/24 0:02:09
OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定

OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定

OpenModScan:免费跨平台 Modbus 主站调试工具,让现场通讯验证一键搞定 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan OpenModScan 是一款开源免…

2026/8/24 0:02:09
用好 Python 上下文管理器:contextlib 让你少写一半 with 代码

用好 Python 上下文管理器:contextlib 让你少写一半 with 代码

用好 Python 上下文管理器:contextlib 让你少写一半 with 代码 with 语句几乎每个 Python 程序员每天都在用:打开文件、加锁、连接数据库。但很多人只停留在 with open(...) 这个层面,一旦需要自己封装资源或复用一段"进入/退出"逻…

2026/8/23 23:57:08