
一、IPC对象基础概念每一个IPC对象消息队列 / 共享内存 / 信号量数组在内核中存在具备唯一key外部键与id内核返回的操作句柄。查看删除IPC对象终端命令ipcs-q#查看消息队列ipcs-m#查看共享内存ipcs-s#查看信号量ipcrm-qmsqid#按id删除消息队列ipcrm-mshmid#按id删除共享内存ipcrm-ssemid#按id删除信号量注意IPC对象内核持久化进程退出不会自动销毁必须手动ipcrm或者代码调用*ctl接口删除。ftok生成key_t键值key_tftok(constchar*pathname,intproj_id);pathname必须是真实存在的文件路径proj_id项目ID仅使用低8位0-255返回成功返回key_t类型key失败返回-1作用不同进程传入同一个pathnameproj_id就能拿到同一个key用来定位同一个内核IPC对象。二、消息队列 message queue本质内核维护的消息链表进程发送带类型的消息块按消息类型接收数据。完整操作流程ftok()生成keymsgget()创建/获取消息队列idmsgsnd()发送消息msgrcv()接收消息msgctl()删除消息队列1. msgget 创建消息队列intmsgget(key_tkey,intmsgflg);keyftok得到的键值msgflgIPC_CREAT不存在就创建IPC_EXCL已存在报错返回成功返回消息队列id失败-12. msgsnd 发送消息intmsgsnd(intmsqid,constvoid*msgp,size_tmsgsz,intmsgflg);msqidmsgget返回idmsgp自定义消息结构体首地址第一个成员必须是long类型消息类型msgsz消息正文字节大小不包含long消息类型msgflg一般填0阻塞模式返回成功0失败-1消息模板示例structmsgbuf{longmtype;//消息类型必须大于0charmtext[128];//消息数据};3. msgrcv 接收消息ssize_tmsgrcv(intmsqid,void*msgp,size_tmsgsz,longmsgtyp,intmsgflg);msgtyp指定接收哪一类消息0代表读取队列第一条消息返回成功返回读到的字节数失败-14. msgctl 消息队列控制intmsgctl(intmsqid,intcmd,structmsqid_ds*buf);cmd参数IPC_STAT获取消息队列状态IPC_SET修改权限IPC_RMID删除消息队列返回成功0失败-1练习需求send.c终端读字符串送入消息队列recv.c读取消息打印输出。三、共享内存 shared memory进程间通信效率最高直接把内核开辟的内存映射到用户进程虚拟地址空间进程直接读写这块内存没有数据拷贝开销。⚠️ 共享内存本身不带同步互斥机制需要配合信号量/锁做访问保护。操作步骤ftok()生成keyshmget()在内核创建共享内存shmat()把共享内存映射到本进程虚拟地址得到可用指针直接读写该内存完成进程通信shmdt()解除当前进程映射不销毁内核对象shmctl(IPC_RMID)销毁内核共享内存对象1. shmget 创建共享内存intshmget(key_tkey,size_tsize,intshmflg);size共享内存字节大小一般为4K整数倍shmflgIPC_CREAT | IPC_EXCL | 0664返回成功返回shmid失败-12. shmat 挂载映射void*shmat(intshmid,constvoid*shmaddr,intshmflg);shmaddr填NULL让操作系统自动选合适虚拟地址返回成功返回映射后的内存首地址失败返回(void*)-13. shmdt 解除映射intshmdt(constvoid*shmaddr);传入shmat返回的地址解除映射不会删除内核中的共享内存。4. shmctl 共享内存控制intshmctl(intshmid,intcmd,structshmid_ds*buf);IPC_STAT获取属性IPC_SET修改权限IPC_RMID删除内核共享内存对象重要考点多个进程shmat挂载同一块共享内存shmdt只是脱离必须shmctlIPC_RMID才真正销毁。四、System-V 有名信号量 semaphore信号量本质内核维护计数器主要用来做进程互斥、同步保护共享内存这类临界资源。操作具备原子性。操作流程ftok获取keysemget 创建/获取信号量数组semctl初始化信号量初值、删除信号量集合semopP操作(申请计数器-1)、V操作(释放计数器1)1. semget 创建信号量数组intsemget(key_tkey,intnsems,intsemflg);nsems信号量数组里面信号量的个数常用1返回成功返回semid失败-12. semctl 信号量控制intsemctl(intsemid,intsemnum,intcmd,...);semnum操作数组中第几个信号量下标从0开始cmdSETVAL设置信号量初始计数值IPC_RMID删除整个信号量数组3. semop P/V操作核心函数intsemop(intsemid,structsembuf*sops,size_tnsops);struct sembuf结构体成员unsignedshortsem_num;//信号量下标shortsem_op;//操作数-1 P申请1 V释放shortsem_flg;//常用0IPC_NOWAIT非阻塞sem_op -1P操作信号量减1资源不够就阻塞sem_op 1V操作信号量加1释放资源重点信号量本身不传输业务数据只做同步互斥经常搭配共享内存一起使用。五、System-V IPC对比总结IPC对象核心用途数据拷贝同步自带销毁方式消息队列传递带类型消息块存在内核拷贝自带队列阻塞msgctl IPC_RMID共享内存大数据高速通信无拷贝直接映射无同步shmctl IPC_RMID信号量进程互斥同步保护临界资源不传输数据只维护计数器原子操作semctl IPC_RMID高频踩坑点IPC对象内核持久化进程退出不会自动回收忘记删除会残留内核资源。ftok同一个文件proj_id才能得到相同key文件删除ftok依然可以生成key。共享内存一定要自己加信号量互斥多进程同时读写直接出现数据错乱。sembuf的sem_op-1代表P1代表V考试高频考点。msgsnd的传入长度msgsz不包含long类型消息类型mtype。