Linux :进程间通信(IPC)与信号
一、信号1. 基本概念信号是用于通知进程某个事件发生的软中断机制是进程间异步通信的一种方式。2. 核心信号与操作SIGINT由ctrlc触发默认功能是终止进程。SIG_IGN忽略该信号SIG_DFL恢复信号的默认行为signal(信号值, 处理行为)修改信号的处理逻辑实现信号功能替换。kill()用于向进程发送指定信号主动触发信号机制。二、进程间通信IPC方式进程间通信核心方式包括管道、共享内存、消息队列、信号量、套接字以下重点整理前四类核心机制。1. 管道管道是基于文件描述符的半双工通信方式数据传输遵循先进先出FIFO分为有名管道和无名管道两类。特性有名管道无名管道名称有文件名存在于文件系统无名称仅通过文件描述符访问进程关系任意有权限的进程仅亲缘进程父子 / 兄弟生命周期随文件系统需手动删除随进程销毁而销毁创建方式mkfifo命令pipe()系统调用1.1 通用特性与注意事项通信模式半双工同一时刻仅能单向传输数据特性字节流无边界若按消息传输需自定义格式长度 数据避免多读 / 少读核心问题管道破裂读端关闭后写端仍写入触发SIGPIPE信号终止写端进程缓冲区阻塞读空 / 写满会阻塞进程需通过fcntl()设置非阻塞属性资源泄漏进程退出前未关闭描述符会导致缓冲区数据丢失。1.2 测试与使用命令行测试读端持续监听while true;do cat 管道文件;done写端写入cat 管道文件。代码操作读管道使用read()函数注意第三个参数不能用初始化的strlen写管道使用write()函数向管道文件写入数据。2. 共享内存共享内存是最快的 IPC 方式通过将同一块内存映射到多个进程的地址空间实现数据直接共享。2.1 核心函数函数功能关键参数 / 返回值shmget()创建 / 获取共享内存key唯一标识size内存大小新建填正数获取填 0shmflgIPC_CREAT创建 权限位返回值成功返回标识符失败返回 - 1shmat()将共享内存映射到进程地址空间shm_idshmget返回值shm_addrNULL系统自动分配地址/ 自定义地址shmflg0读写/SHM_RDONLY只读返回值映射后的内存地址2.2 操作流程创建共享内存shmget(key, size, IPC_CREAT | 0666)映射到进程shmat(shm_id, NULL, 0)进程读写共享内存数据解除映射可选shmdt()删除共享内存释放资源通过shmctl()设置IPC_RMID。2.3 练习场景读进程持续读取共享内存中的数值写进程持续向共享内存写入数值。3. 信号量信号量用于进程间同步与互斥本质是受保护的整数计数器通过原子操作修改值控制共享资源的访问。3.1 核心概念原子操作信号量的加减操作不可中断避免多进程并发修改导致数据不一致堵塞机制信号量值为 0 时获取该信号量的进程阻塞直到其他进程释放资源类型二值信号量值为 0/1实现互斥类似锁一次仅一个进程访问计数信号量值为非负数控制多个相同资源的并发访问P/V 原语P 操作减 1结果≥0 则进程继续否则阻塞V 操作加 1永远不阻塞若有阻塞进程则唤醒一个临界资源同一时刻仅允许一个进程访问的资源临界区访问临界资源的代码段。3.2 核心函数函数功能关键参数 / 返回值semget()创建 / 获取信号量集key唯一标识nsems信号量个数新建 / 获取均需 0semflgIPC_CREAT 权限返回值成功返回标识符失败返回 - 1semctl()控制信号量集设置 / 获取 / 删除semid信号量集标识符semnum信号量索引整体操作忽略cmdSETVAL设初始值/GETVAL取值/IPC_RMID删除可变参数union semun自定义联合体semop()执行信号量 P/V 操作semid信号量集标识符sops指向sembuf结构体的指针含sem_num索引、sem_op±1、sem_flgSEM_UNDOnsops操作数个数3.3 关键结构体 / 联合体联合体semun自定义union semun { int val; // 用于SETVAL设置信号量值 struct semid_ds *buf; // 用于IPC_STAT/IPC_SET状态信息 unsigned short *array; // 用于GETALL/SETALL批量操作 struct seminfo *_buf; // 用于IPC_INFO系统限制 };结构体sembufstruct sembuf { unsigned short sem_num; // 信号量索引 short sem_op; // 操作类型1/V操作-1/P操作 short sem_flg; // 标志位常用SEM_UNDO异常退出时撤销修改 };3.4 操作流程创建信号量集semget(key, nsems, IPC_CREAT | 0600)设置信号量初始值semctl(semid, 0, SETVAL, {.val 1})二值信号量执行 P/V 操作通过semop()传入sembuf结构体如sem_op -1为 P 操作sem_op 1为 V 操作释放资源semctl(semid, 0, IPC_RMID)删除信号量集。三、补充工具ipcs查看系统中 IPC 资源共享内存、信号量、消息队列ipcrm手动删除 IPC 资源配合ipcs结果清理。