原理:
用户组织一个 带有类型的数据块,添加到消息队列中,其他进程从该消息队列中取出对应类型的数据块
本质: 操作系统在内核为用户创建并且维护的一个队列
并且该队列为用户提供了一个两个进程之间发送具有类型的数据块的方法
不足:
数据块的长度有上限(MSGMAX)
消息队列总字节数有上限(MSGMNB)
消息队列个数有上限(MSGMNI)
创建消息队列:
int msgget(key_t key, int msgflag);
key:消息队列的标识符(名字)
msgflag:权限标志位,一般为(IPC_CREAT | 0666(访问权限))
IPC_CREAT:如果该消息队列不存在,则创建
IPC_EXCL:如果该消息队列存在,则创建失败
IPC_NOWAIT:若阻塞,则报错返回
创建成功:返回该消息队列的操作句柄(标识码)(不是文件描述符)
创建失败:返回-1
创建成功之后
操作系统为用户维护一个消息队列结构体(msqid_ds)
msqid_ds中有一个 ipc对象(ipc_perm),当中有key值(身份标识),并且仍然由操作系统维护
注:ipc_perm结构体对象是 消息队列、共享内存以及信号量都具有的一个数据结构
查看消息队列
命令:ipcs -q
数据块结构体:
struct msgbuf{
long mtype;
char mtext[1];
};
mtype:数据块的类型
mtext:数据块的内容
注:数据块大小必须小于系统规定的上限值
消息队列结构体(msqid_ds)图示分析:
发送数据块(即:将一个数据块放入到消息队列中)
int msgsnd(int msgid, const void msgp, size_t msgsz, int msgflg);*
msgid:该消息队列的标识码
msgp:将要放入消息队列的数据块
msgsz:数据块长度(不包含保存数据块类型的长整型)
msgflg:控制消息队列将要发生的事情,默认0
成功返回0,失败返回-1.
接收数据块(即:从消息队列中拿出对应类型的数据块)
ssize_t msgrcv(int msgid, void msgp, size_t msgsz, long msgtype, int msgflg);*
msgid:消息队列标识码
msgp:接收消息队列中的数据块指针(输出型参数)
msgsz:数据块长度(不包含保存数据块类型的长整型)
msgtyp:将要接收的数据块的类型,即:msgbuf.mtype的内容
msgflg:控制消息队列将要发生的事情,默认0
成功返回数据块长度,失败返回-1
删除消息队列
1.命令删除:
ipcs -q 查看
ipcrm -q + id 按 id 号移除消息队列
ipcrm -Q + key <键> 按键值移除消息队列
2.函数删除:
int msgctl(int msgid, int cmd, struct msgid_ds buf);
msgid:消息队列标识码
cmd:将要执行的操作
IPC_STAT:get ipc_perm options
IPC_SET:set ipc_perm options
IPC_RMID:删除
buf:获取消息队列信息*(即:得到该消息队列的msgid_ds结构体信息)、不需要获取则置NULL
注:使用完消息队列资源之后必须删除,内核不会清理,其生命周期随内核!!
关于进程间通信—管道的内容,大家可以参考一下:https://blog.csdn.net/Code_ZX/article/details/84986104
谢谢大家的支持!!