ipc对象之消息队列
1.概念
消息队列是System V IPC对象的一种,用来进程间通信
消息队列由消息队列ID来唯一标识
消息队列是一个消息的列表。用户可以在消息队列中添加消息、读取消息
消息队列可以按照类型来发送、接收消息
在内核空间是以链表的形式存储的
2.相关API
合成key值
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname,int proj_id)
pathname:一个存在的文件或目录名
proj_id:0~255之间的非负整数
成功返回key值,失败返回-1
创建消息队列通道
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key,int flag)
key:和消息队列相关联的key值
flag:消息队列的访问权限
成功返回消息队列ID,出错返回-1
添加消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid,const coid *msgp,size_t size,int flag)
msqid:消息队列的ID
msgp:指向消息的指针。常用消息结构msgbuf如下:
struct msgbuf
{
long mtype; //消息类型
char mtext[N]; //消息正文
}
size:发送的消息正文的字节数
flag:
IPC_NOWAIT消息没有发送完成函数也会立即返回。
0直到发送完成函数才返回
成功返回0,出错返回-1
读取消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg,h>
int msgrcv(int msgid,void *msgp,size_t size,long msgtype,int flag)
msqid:消息队列的ID
msgp:接收消息的缓冲区
size:要接受的消息正文的字节数
msgtype:
0:接收消息队列中第一个消息
大于0:接收消息队列中第一个类型为msgtyp的消息
小于0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息
flag:
0:若无消息函数会一直阻塞
IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG
成功接收到消息的长度,出错返回-1
删除消息队列
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msgqid,int cmd,struct msqid_ds *buf)
msqid:消息队列的队列ID
cmd:
IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中
IPC_SET:设置消息队列的属性。这个值取自buf参数
IPC_RMID:从系统中删除消息队列
bus:消息队列缓冲区
成功返回0,出错返回-1
3.测试
msgwrite.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
#define N 128
#define MSGLEN (sizeof(MSGT) - sizeof(long))
/* 定义通信结构体 */
typedef struct msgbuf
{
long mtype; /* 类型 */
char mtext[N]; /* 数据 */
}MSGT;
int main()
{
key_t key;
int msgid = 0;
int ret = 0;
/* 合成key值 */
key = ftok(".",3);
if(key < 0)
{
perror("ftok error\n");
return -1;
}
/* 创建消息队列 */
msgid = msgget(key,IPC_CREAT|0666);
if(msgid < 0)
{
perror("msgget error\n");
return 0;
}
/* 赋值 */
MSGT data = {1L,"hweriwe"};
//scanf("%ld %s",&data.mtype,data.mtext);
/* 发送消息 */
ret = msgsnd(msgid,&data,MSGLEN,0);
if(ret < 0)
{
perror("msgsnd error\n");
return -1;
}
return 0;
}
msgread.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <errno.h>
#define N 128
#define MSGLEN (sizeof(MSGT) - sizeof(long))
typedef struct msgbuf
{
long mtype;
char mtext[N];
}MSGT;
int main()
{
key_t key;
int ret = 0;
MSGT data;
int msgid = 0;
/* 合成key值 */
key = ftok(".",3);
if(key < 0)
{
perror("ftok error\n");
return -1;
}
/* 创建消息队列 */
msgid = msgget(key,IPC_CREAT|0666);
if(msgid < 0)
{
perror("msgget error\n");
return -1;
}
/* 接收消息 */
ret = msgrcv(msgid,&data,MSGLEN,0,0);
if(ret < 0)
{
perror("msgrcv error\n");
}
printf("mtype:%ld mtext:%s\n",data.mtype,data.mtext);
/* 销毁消息队列 */
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
4.相关命令
ipcs 可以查看ipc对象
ipcrm 可以删除ipc对象
ntf(“mtype:%ld mtext:%s\n”,data.mtype,data.mtext);
/* 销毁消息队列 */
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
[外链图片转存中...(img-tyjlFSdC-1662566629522)]
#### 4.相关命令
ipcs 可以查看ipc对象
ipcrm 可以删除ipc对象