进程间通信之System V消息队列

struct ipc_perm:这是System V版本系列进程间通信所用到的一个公共版结构体。也就是Linux内核为每个IPC对象维护一个数据结构。
第一字段,这个属性非常重要,它称之为ipckey。
进程间通信的方式其实本质上它们都得在内核中申请一定的资源,而ipckey其实就是在描述着内存中惟一 一个消息队列/一块共享内存/一个信号量集这样的资源,因为一个操作系统可以创建很多个消息队列。

System V消息队列
消息队列生命周期随内核,必须手动删除,否则不会自动清除,除非重启。
不光是消息队列,所有的System V IPC都需要手动释放资源,因为它们的生命周期都随内核。
队列就是一个数据结构,具有先进先出的特性。其实消息队列本质上也是一个队列。但消息队列是一个比较广泛的概念,它不光在内核中应用,也在很多其他的场景中应用。
消息队列中的元素具备数据类型(这里说的数据类型,这个类型二字指的不是C中的那个类型,指的是我们具体业务场景中的类型),并且也不是按照严格的先进先出(基于这种类型,就可以做到不需要进行一个严格意义上的先进先出,而是每次出队列的时候按照你指定的类型进行先进先出(超声科室中有个医生出来说,过来一个检查胃的,虽然产检的排在第一位置,但是并不是她出队,而是在检查胃中排在靠前的先出))。

struct msqid_ds:描述一个消息队列对应的结构体,消息队列在内核中其实就是一个链表。
消息队列的不足:
操作系统上消息队列的总数有一个上限(MSGMNI),每个消息队列的总字节数有一个上限(MSGMNB),每个消息的字节数有一个上限(MSGMAX)。

系统调用msgget():创建和打开一个消息队列
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msggrt(key_t key, int msgflg);//成功返回消息队列的id;失败返回-1,并设置errno。
参数2:
1、IPC_CREAT,如果消息队列不存在就创建,如果存在就打开。
2、IPC_CREAT | IPC_EXCL:按位或,两个都是要理解成位图的,把这两个选项结合到一起。
IPC_EXCL必须配合IPC_CREAT使用,不能单独使用。含义是如果消息队列存在,打开就会失败。如果单纯只是创建,不用打开的话,就可以IPC_EXCL配着合IPC_CREAT使用。
参数1:创建一个消息队列或者打开一个消息队列都得指定好你要创建谁、打开谁,key_t本质上就是int,就像pid_t一样。
但是key怎样获得?ftok()
#include<sys/types.h>
#include<sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);//专门用于生成ipckey的
一个电脑上可能跑着好几个项目,每个项目里面可能又会使用好几个消息队列,在生成ipckey的时候就是根据你当前这个项目的目录是什么,以及你这个项目的序号是什么来决定对应的ipckey。
其中,传的参数完全相同的话,生成的ipckey就会相同。
消息队列是用于进程间通信,所以得让多个进程通过ipckey打开同一个消息队列。

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);//销毁消息队列
成功返回0;失败返回-1,并设置errno。

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
失败时,两个函数均返回-1,并用errno表示错误,否则msgsnd()返回0,msgrcv()返回实际字节数。

在接口的使用中还有一些需要注意的细节,请参考代码注释。
代码
当你运行server程序后,对其异常终止,当你再次启动时,发现msgget:File exists报错。
ipcs -q:显示消息队列资源
ipcrm -q+msqid:手动删除指定消息队列
随后启动server,OK。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值