目录
★ 什么是消息队列?
- 是Linux的一种通信机制,这种通信机制传递的数据具有某种结构,而不是简单的字节流;
- 消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构;
- 向消息队列中写数据,实际上是向这个数据结构中插入一个新结点;从消息队列汇总读数据,实际上是从这个数据结构中删除一个结点;
- 消息队列提供从一个进程向另外一个进程发送一块数据的方法;
- 消息队列也有管道一样的不足,就是每个数据块的最大长度是有上限的,系统上全体队列的最大总长度也有一个上限。
★ 流程摘要
① 创建消息队列,使用msgid接收标识符;
② 写入内容到消息队列;
③ 读取消息队列内容;
④ 根据实际情况是否删除消息队列
★ msgget函数
msgget函数:创建消息队列/获取消息队列标识符(使用msgid接收标识符)
函数原型:
int msgget(key_t key, int msgflg);
key:需要通信的进程双方建立起的队列标识码,使用ftok函数来获取;
msgflg:访问权限;
返回值:如果成功,返回值将是消息队列标识符(非负整数),否则为-1,errno表示错误。
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> int main() { key_t key = ftok("msg1.c",1); int msgid = msgget(key,IPC_CREAT|0666); if(msgid == -1){ printf("msgget error!\n"); } printf("msgget success!msgid=%d\n",msgid); return 0; }
★ msgsnd函数
msgsnd函数:写入内容到消息队列
函数原型:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
int msqid:消息队列标识码,即msgid;
const void *msgp:指向消息类型的指针,原型是一个结构体,如下:
struct msgbuf { long mtype; //消息类型 char mtext[1]; //消息内容 };
size_t msgsz:发送消息的字节数;
int msgflg:如果为0,直到发送完成函数才返回,即阻塞发送;IPC_NOWAIT,消息没有发送完成,函数也返回,即非阻塞发送;
返回值:成功返回0,失败返回-1;
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> struct msgbuf{ long mtype; char mtext[32]; }; int main() { key_t key = ftok("msg1.c",1); int msgid = msgget(key,IPC_CREAT|0666); if(msgid == -1){ printf("msgget error!\n"); } printf("msgget success!msgid=%d\n",msgid); // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); struct msgbuf snd = {1,"hellobaby!"}; msgsnd(msgid,&snd,sizeof(snd.mtext),0); return 0; }
★ msgrcv函数
msgrcv函数:读取消息队列内容
函数原型:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
int msqid:消息队列标识码,即msgid;
void *msgp:指向消息类型的指针;
size_t msgsz:读取消息的字节数;
long msgtyp:接收消息的类型/标识;
Int msgflg:0表示阻塞读取;IPC_NOWAIT表示非阻塞读取;
返回值:成功返回接收到消息的长度,失败返回-1;
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> struct msgbuf{ long mtype; char mtext[32]; }; int main() { key_t key = ftok("msg1.c",1); int msgid = msgget(key,IPC_CREAT|0666); if(msgid == -1){ printf("msgget error!\n"); } printf("msgget success!msgid=%d\n",msgid); // ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); struct msgbuf snd = {1,"hellobaby!"}; msgrcv(msgid,&snd,sizeof(snd.mtext),1,0); printf("mtype:%ld\n",snd.mtype); printf("mtext:%s\n",snd.mtext); return 0; }
★ msgctl函数
msgctl函数: 删除消息队列
函数原型:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msqid:消息队列标识码,即msgid;
int cmd:IPC_STAT 读取消息队列的属性,然后把它保存在buf指向的缓冲区;
IPC_SET 设置消息队列的属性,这个值取至buf中参数
IPC_RMID 删除消息队列;
struct msqid_ds *buf: 消息队列的缓冲区,如果参数cmd写IPC_RMID时,此缓冲区内写NULL就行。
返回值:成功返回0,失败返回-1.
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <stdio.h> int main() { // int msgctl(int msqid, int cmd, struct msqid_ds *buf); msgctl(3,IPC_RMID,NULL); //上面示例代码的msgid=3 return 0;
★ 消息队列相关指令
ipcs :显示消息队列,共享内存,信号量通信的相关数据;
ipcs -q:只显示消息队列信息;
ipcrm -q:删除消息队列标识符。