消息队列:进程间都访问同一个队列(链表)
发送消息: 向队列添加一个节点
接收消息:从队列读取一个节点
ipcs -q查看所有的消息队列
使用方式,
1、创建key值
2、创建或打开消息队列
3、读取或发送消息队列
4、消息队列删除
函数原型:key_t ftok(const char *pathname, int proj_id);
功能:生成key值
参数:pathname 路径名(用户自定义)
proj_id 用户自定义 传字符
返回值: 成功 key值
失败 -1
1)创建或打开消息队列
函数原型:int msgget(key_t key, int msgflg);
功能:创建或打开一个消息队列
参数:key 键值 (0,ftok函数返回值)
msgflg 1)IPC_CREAT|IPC_EXCL|0664
如果队列不存在,则创建;如果存在,返回EEXIST
创建并打开消息队列
2)0664 打开消息队列
返回值:成功 消息队列的标识符
失败 -1
2)发送消息
函数原型:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向队列的末尾添加一个消息
参数:msqid 消息队列的标识符
msgp 发送的节点
struct msgbuf {
long mtype; 消息的类型
char mtext[1]; 消息正文(数组,变量,结构体,自定义)
};
msgsz 消息正文的大小 sizeof(struct msgbuf)- sizeof(long)
msgflg 0 阻塞等待
IPC_NOWAIT 非阻塞,EAGAIN
返回值:成功 0
失败 -1
3)接收消息
函数原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
功能:从消息队列中移除一个消息
参数:msqid 消息队列的标识符
msgp 保存读取的消息(定义与写入时一致)
msgsz 消息正文的大小
msgtyp 0 读取消息队列中的第一个消息
>0 读取消息队列中类型等于msgtyp的第一条消息
<0 读取消息队列中类型不小于|msgtyp|,且类型最小的第一个消息
msgflg 0 阻塞等待
IPC_NOWAIT
返回值:成功 消息正文的大小
失败 -1
4)控制消息队列(设置消息队列的属性、获取消息队列的属性、删除消息队列)
函数原型:int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:对消息队列控制
参数:msqid 消息队列的标识符
cmd 控制
IPC_RMID 删除消息队列
IPC_STAT 获取消息队列的属性(将属性保存在第三个参数)
IPC_SET 设置消息队列的属性
buf 存放属性的结构体
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
返回值:成功 0
失败 -1
消息队列发送
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define SIZE sizeof(struct msgbuf) - sizeof(long)
struct msgbuf{
long mtype;
//消息正文
int a;
char b;
};
int main(int argc, const char *argv[])
{
//获得key值
key_t key;
if((key = ftok(".", 'q')) < 0){
perror("ftok error");
return -1;
}
//创建或打开消息队列
int msqid;
struct msgbuf msgbuf;
if((msqid = msgget(key, IPC_CREAT|IPC_EXCL|0664)) < 0){
if(errno != EEXIST){
perror("msgget error");
return -1;
}
else{
//如果存在,则打开消息队列
msqid = msgget(key, 0664);
}
}
msgbuf.mtype = 100;
msgbuf.a = 10;
msgbuf.b = 'q';
msgsnd(msqid, &msgbuf, SIZE, 0);
system("ipcs -q");
return 0;
}
消息队列接收
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#define SIZE sizeof(struct msgbuf) - sizeof(long)
struct msgbuf{
long mtype;
//消息正文
int a;
char b;
};
int main(int argc, const char *argv[])
{
//获得key值
key_t key;
if((key = ftok(".", 'q')) < 0){
perror("ftok error");
return -1;
}
//创建或打开消息队列
int msqid;
struct msgbuf msgbuf;
if((msqid = msgget(key, IPC_CREAT|IPC_EXCL|0664)) < 0){
if(errno != EEXIST){
perror("msgget error");
return -1;
}
else{
//如果存在,则打开消息队列
msqid = msgget(key, 0664);
}
}
//接收消息
msgrcv(msqid, &msgbuf, SIZE, 100, 0);
printf("a = %d b = %c\n", msgbuf.a, msgbuf.b);
//删除消息队列
msgctl(msqid, IPC_RMID, NULL);
system("ipcs -q");
return 0;
}