**********************消息队列************************
*-*-*-*-*-*-*关于key和id的解释*-*-*-*-*-*-*
id就是指每个消息队列的标记值,
而key值就是表示如何找到这个消息队列,
对于一个准备发送消息的进程,通过ftok()函数,
可以将指定的文件加上自定义的值一般是项目ID作为key值,
创建一个消息队列,而在另一个准备接受的进程里,
它不知道要在哪个消息队列里接收消息,
于是它也通过一个指定的文件加上自定义的值例如项目ID作为key值,
后通过key值找到所属的消息队列。
所以这个key值属于要通信的进程双方互相沟通好的,
作为在内核里找到它们专属的消息队列的桥梁。
*******************----------*******************
key_t ftok(const char *pathname, int proj_id);
通过一个指定的文件加上自定义的值来产生一个共识的key;
key值就是表示如何找到这个消息队列
int msgget(key_t key, int msgflg);
函数被用来创建新的消息队列或获取已有的消息队列。
第一个参数是消息队列对象的关键字key
第二个参数
***IPC_CREAT 不存在新建,存在打开
***IPC_EXCL 和IPC_CREAT一起用,功能不存在新建,存在返回-1,
***权限0666
返回值:ID 创建的消息队列的标识符;
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);
msqid:消息队列的识别码
msgp:指向消息缓冲区的指针,
此位置用来暂时存储发送和接收的消息,
是一个用户可定义的通用结构,形态如下
struct msgbuf {
long mtype; /* 消息类型,必须 > 0 */
char mtext[1]; /* 消息文本 */
};
msgsz 消息的大小(发送接收端应尽量一致)
msgtyp 接收特有,从消息队列内读取的消息标志,为0表示读取消息队列的所有消息
msgflg 0 --->忽略以下操作
IPC_NOWAIT --->非阻塞读出、写入消息
MSG_EXCEPT --->读取标识不等于msgtyp的第一个消息
MSG_NOERROR --->消息尺寸比msgsz大时,截断消息而不报错
返回值
成功 msgsnd --->0
msgrcv --->真正读取的字节数
失败 --->-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数
msqid --->消息队列的ID
cmd --->
IPC_STAT --->获取该MSG的信息,存储在结构体msqid_ds中
IPC_SET --->设置该MSG的信息,存储在结构体msqid_ds中
IPC_RMID --->立即删除该MSG,并且唤醒所有阻塞在该MSG上的进程,同时忽略第三个参数
IPC_INFO --->获取关于当前系统中MSG的限制值信息
MSG_INFO --->获取关于当前系统中MSG的相关资源消耗信息
buf --->相关信息结构体缓冲区,不需要就写NULL
返回值
成功 --->
IPC_STAT --->0
IPC_SET --->0
IPC_RMID --->0
IPC_INFO --->内核中记录所有消息队列信息的数组的下标最大值
MSG_INFO --->内核中记录所有消息队列信息的数组的下标最大值
失败
--->-1
注意
(1)ICP_STAT获得的属性信息被存放在以下结构体中
struct msqid_ds {
struct ipc_perm msg_perm; /* 权限相关信息 */
time_t msg_stime; /*最后一次发送消息的时间 */
time_t msg_rtime; /*最后一次接收消息的时间 */
time_t msg_ctime; /* T最后一次状态变更的时间 */
unsigned long __msg_cbytes; /* 当前消息队列中的数据尺寸 */
msgqnum_t msg_qnum; /* 当前消息队列中的消息个数 */
msglen_t msg_qbytes; /* 消息队列的最大数据尺寸 */
pid_t msg_lspid; /* 最后一个发送消息的进程PID*/
pid_t msg_lrpid; /* 最后一个接收消息的进程PID */
};
(2)权限相关信息用如下结构体
struct ipc_perm {
key_t __key; /* 当前消息队列的键值key */
uid_t uid; /* 当前消息队列所有者的有效UID */
gid_t gid; /* 当前消息队列所有者的有效GID */
uid_t cuid; /* 当前消息队列创建者的有效UID */
gid_t cgid; /* 当前消息队列创建者的有效GID */
unsigned short mode; /* 消息队列的读写权限 */
unsigned short __seq; /* 序列号 */
};
(3)当使用IPC_INFO时,需要定义一个如下结构体来获取系统消息队列的限制值信息,并且将这个结构体指针强制类型转化为第三个参数的类型
struct msginfo {
int msgpool; /* 系统消息总尺寸(千字节为单位)最大值 */
int msgmap; /* 系统消息个数最大值 */
int msgmax; /* 系统单个消息尺寸最大值 */
int msgmnb; /* 写入消息队列字节数最大值 */
int msgmni; /* 系统消息队列个数最大值 */
int msgssz; /* 消息段尺寸 */
int msgtql; /* 系统中所有消息队列中的消息总数最大值 */
unsigned short int msgseg;/* 分配给消息队列的数据段的最大值 */
};
(4)使用MSG_INFO时,跟IPC_INFO一样也是获得一个msginfo结构体的信息,但有如下几点不同
A)成员msgpool记录的是系统当前存在的MSG的个数总和
B)成员msgmap 记录的是系统当前所有MSG中的消息个数总和
C)成员msgtql 记录的是系统当前所有MSG中的所有消息的所有字节数总和
消息队列函数
最新推荐文章于 2024-10-01 18:51:18 发布
本文详细介绍了Linux消息队列中的key和id概念,以及关键函数如ftok、msgget、msgsnd、msgrcv和msgctl的使用方法。重点讲解了如何通过key在进程间共享消息队列,并展示了消息队列权限和统计信息的管理方式。
摘要由CSDN通过智能技术生成