1,概念:
消息队列的最佳定义是:内核地址空间中的内部链表。消息可以顺序地发送到队列中,并以几种不同的方式从队列中获取。当然,每个消息队列都是由 IPC 标识符所唯一标识的。
2,msgget()
msgget ( ) 的第一个变元是关键字的值 ( 可以调用 ftok ( ) 的返回值 ) 。这个关键字的值将被拿来与内核中其他消息队列的现有关键字值相比较。比较之后,打开或者访问操作依赖于 msgflg 变元的内容。
• IPC_CREAT — 如果在内核中不存在该队列,则创建它。
• IPC_EXCL — 当与 IPC_CREAT 一起使用时,如果队列早已存在则将出错。
如果只使用了 IPC_CREAT, msgget ( ) 或者返回新创建消息队列的消息队列标识符,或者会返回现有的具有同一个关键字值的队列的标识符
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgget(key_t key,int msgflag)
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
0xffffffff 0 addia 666 0 0
0x61091e8d 32769 addia 666 0 0
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int main()
{
int qid;
key_t key;
key =111;
qid=msgget(key,IPC_CREAT|0666);//创建一个消息队列
if(qid<0)
{
perror("msgget error");
exit(1);
}
printf("creat queue id :%d\n",qid);//输出消息队列的id
system("ipcs -q");//查看系统的ipc
exit(0);
}
addia@addia-Lenovo-B470:~/演示代码$ ./msgget
creat queue id :65538
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
0xffffffff 0 addia 666 0 0
0x61091e8d 32769 addia 666 0 0
0x0000006f 65538 addia 666 0 0
2,msgctl()
#include <sys/msg.h>
int msgctl( int msqid, int cmd , struct msqid_ds *buf );
cmd 参数详解
cmd | 操 作 |
IPC_STAT | 取队列的 msqid_ds 结构,将它存放在 buf 所指向的结构中(需要 buf 参数) |
IPC_SET | 使用 buf 所指向结构中的值对当前队列的相关结构成员赋值,其中包括:msg_perm.uid 、 msg_perm.gid 、 msg_perm.mode 以及 msg_perm.cuid 。该命令只能由具有以下条件的进程执行:进程有效用户 ID 等于 msg_perm.cuid 或msg_perm.uid 超级用户进程。其中只有超级用户才可以增加队列的 msg_qbytes的值 |
IPC_RMID | 删除队列,并清除队列中的所有消息。此操作会影响后续进程对这个队列的相关操作。该命令只能由具有以下条件的进程执行。进程有效用户 ID 等于msg_perm.cuid 或 msg_perm.uid ,超级用户进程 |
buf是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员:
struct msgid_ds
{
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
};
成功时返回0,失败时返回-1
.
3,msgrcv()
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);
int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);
struct my_message{
long int message_type;
/* The data you wish to transfer*/
};
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
struct msg_buf
{
int mtype;
char data[255];
};
int main()
{
key_t key;
int msgid;
int ret;
struct msg_buf msgbuf;
key=ftok(".",'a');
printf("key =[%x]\n",key);
msgid=msgget(key,IPC_CREAT|0666); /*通过文件对应*/
if(msgid==-1)
{
printf("create error\n");
return -1;
}
msgbuf.mtype = getpid();
strcpy(msgbuf.data,"test haha");
ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);
if(ret==-1)
{
printf("send message err\n");
return -1;
}
memset(&msgbuf,0,sizeof(msgbuf));
ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);
if(ret==-1)
{
printf("recv message err\n");
return -1;
}
printf("recv msg =[%s]\n",msgbuf.data);
}
addia@addia-Lenovo-B470:~/演示代码$ ./msg
key =[61091e8d]
recv msg =[test haha]