Linux相关概念和易错知识点(52)(基于System V的信号量和消息队列)
目录1、System V信号量1信号量的本质与核心原理2PV原语均为原子操作a. P原语申请资源b. V原语归还资源3System V信号量接口a. 创建信号量集 semgetb. 控制信号量 semctlc. PV操作 semop4信号量管理2、System V 消息队列1消息队列特点2消息队列接口函数a. 创建 / 获取消息队列 msggetb. 消息队列控制 msgctlc. 发送消息 msgsndd. 接收消息 msgrcv3命令行管理之前我分享过基于System V的共享内存的使用上篇文章也引入mmap分析了其底层实现即共享映射文件缓冲区使得不同进程看到同一块区域本篇文章会继续分享System V标准下的信号量和消息队列。整体难度不大不需记忆接口了解即可因此本文借助AI生成仅做简单记录和介绍。1、System V信号量1信号量的本质与核心原理无论是POSIX还是System V标准下信号量本质是一个计数器即资源的预定机制主要用于进程间同步与互斥管理在用环形队列实现生产者消费者模型中有很大用处。信号量操作分为P操作申请资源与V操作归还资源。信号量计数器s的含义s 0表示当前可用资源的个数s 0表示无可用资源且无等待进程s 0表示无可用资源|s|为等待队列中进程的个数内核中信号量可由结构体表示structsemaphore{intvalue;structPCB*queue;};2PV原语均为原子操作a. P原语申请资源执行 value–判断 value 0若成立说明资源不足将当前进程加入等待队列并阻塞进程调度切换等待被唤醒voidP(structsemaphore*sem){sem-value--;if(sem-value0){add_to_queue(sem-queue,current_process);block_current_process();}}b. V原语归还资源执行 value判断 value 0若成立说明有进程在等待从等待队列唤醒一个进程至就绪态唤醒后的进程可重新尝试申请信号量voidV(structsemaphore*sem){sem-value;if(sem-value0){structPCB*procremove_from_queue(sem-queue);wake_up_process(proc);}}3System V信号量接口a. 创建信号量集 semgetintsemget(key_t key,intnsems,intsemflg);key唯一标识与共享内存规则一致nsems信号量集中信号量的个数semflg支持 IPC_CREAT 与 IPC_EXCL返回值成功返回 semid失败返回 -1b. 控制信号量 semctlintsemctl(intsemid,intsemnum,intcmd,...);semid信号量集标识符semnum信号量下标从0开始cmdSETVAL初始化单个信号量该操作不具备原子性IPC_RMID删除整个信号量集第二个参数无意义返回值失败返回 -1c. PV操作 semopintsemop(intsemid,structsembuf*sops,size_t nsops);sops操作结构体数组nsops数组长度可同时对多个信号量执行原子操作例如一个P、一个V返回值成功 0失败 -14信号量管理查看信号量ipcs -s删除信号量ipcrm -sSystem V 信号量生命周期随内核进程退出不会自动释放必须手动删除通常在析构函数中完成释放逻辑。2、System V 消息队列1消息队列特点a.允许任意进程间通信消息队列是内核提供的 System V IPC 机制不要求进程之间存在亲缘关系只要多个进程通过同一个 key 访问同一个消息队列即可实现数据收发支持无关联进程间通信。b.消息自带类型标识可按类型选择性接收每条消息必须以一个 long 类型的消息类型字段开头接收方可以指定只接收某一类型的消息不匹配类型的消息会继续保留在队列中也可以不指定类型直接读取最早消息实现消息分类与分发。c.支持全双工通信通信双方可以使用不同消息类型分别进行发送和接收无需切换读写方向双向通信互不干扰天然实现全双工。d.生命周期随内核消息队列创建后会持续存在于内核中进程退出不会自动删除只有通过调用msgctl(IPC_RMID) 或系统重启才会销毁。e.面向数据块传输以消息为单位传输每条消息独立不同于管道的字节流传输边界清晰。2消息队列接口函数a. 创建 / 获取消息队列 msggetintmsgget(key_t key,intmsgflg);key消息队列的唯一标识符可通过 ftok 生成或手动指定msgflg权限位 创建标志IPC_CREAT队列不存在则创建存在则返回已存在队列 IDIPC_EXCL与 IPC_CREAT 配合使用队列已存在则报错确保新建队列例IPC_CREAT | 0666返回值成功返回消息队列 ID msqid失败返回 -1b. 消息队列控制 msgctlintmsgctl(intmsqid,intcmd,structmsqid_ds*buf);cmdIPC_RMID删除消息队列此时 buf 传 NULLIPC_STAT获取队列属性信息存入 bufIPC_SET设置队列属性常用于删除队列msgctl(msqid, IPC_RMID, NULL);c. 发送消息 msgsndintmsgsnd(intmsqid,constvoid*msgp,size_t msgsz,intmsgflg);msgp指向自定义消息结构体指针结构体必须以 long mtype 开头msgsz消息数据部分长度不包含 mtype 字段msgflg一般为 0阻塞发送或 IPC_NOWAIT非阻塞消息结构体示例structmsgbuf{longmtype;charmtext[1024];};d. 接收消息 msgrcvintmsgrcv(intmsqid,void*msgp,size_t msgsz,longmsgtyp,intmsgflg);msgtyp要接收的消息类型0接收队列中第一条任意类型消息0接收指定类型的第一条消息0接收类型 ≤ |msgtyp| 的最小类型消息msgsz数据缓冲区大小msgflg一般为 0阻塞或 IPC_NOWAIT、MSG_NOERROR 等3命令行管理查看消息队列ipcs -q删除消息队列ipcrm -q msqid
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2501248.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!