消息队列是类似于管道,又类似于共享内存的进程间通信的方式.该方式使用的是采用链式存储的方式来存储消息的,而且读取过了以后该消息会被删除.而且消息会被编号,可以发送和读取不同编号的消息,方便传递不通的消息.而创建的过程和共享内存类似,但是不用进行映射,直接将获取的Id使用即可.
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);//创建消息队列
返回值为消息队列的Id
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//发送消息,成功返回0,失败返回-1
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);//接收消息,成功返回接受的字节数,失败返回-1
参数:第一个均为Id,使用相同key可以生成相同的id
msgp:结构体,通常的形式为
struct msgp {
long mtype; // 消息类型,必须 > 0,用于区别不同类型的消息
char mtext[16]; // 消息文本
};
msgsz:消息文本的大小
msgflg:设置是否发送或者接受堵塞,0为堵塞,IPC_NOWAIT为非堵塞
#include <sys/msg.h>
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );//消息队列属性读取,设置,删除
mesqid:消息队列的id
cmd:
IPC_STAT
读取消息队列的数据结构msqid_ds,并将其存储在b u f指定的地址中
IPC_SET
设置消息队列的数据结构msqid_ds中的ipc_perm元素的值。这个值取自buf参数
IPC_RMID
从系统内核中移走消息队列
buf:读取或者设置属性存放的对象,用作删除时为NULL
写消息队列:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <string.h> struct msgbuf { long mtype; // 消息类型,必须 > 0 char mtext[8]; // 消息文本 }; int main(int argc,char *argv[]){ int key = 0; int msqid = 0; struct msgbuf buf; strcpy(buf.mtext,"hello");//要发送的信息 buf.mtype = 1;//信息的类型 key = ftok("sig.c",0); msqid = msgget(key,IPC_CREAT | 0666); if(msqid > 0){ printf("message queue succeed "); }else{ printf("creat failed "); return -1; } int i = 0; while(i < 6){ msgsnd(msqid,(void *)&buf,strlen(buf.mtext),0); sleep(2); i++; } msgctl(msqid,IPC_RMID,NULL); return 0; }
读消息队列:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/types.h> #include <string.h> struct msgbuf { long mtype; // 消息类型,必须 > 0 char mtext[8]; // 消息文本 }; int main(int argc,char *argv[]){ int key = 0; int msqid = 0; struct msgbuf buf; buf.mtype = 1; strcpy(buf.mtext,"hello"); key = ftok("sig.c",0); msqid = msgget(key,IPC_CREAT | 0666); if(msqid > 0){ printf("message queue succeed "); }else{ printf("creat failed "); msgctl(msqid,IPC_RMID,NULL); return -1; } int i = 0; while(i < 6){ sleep(2); msgrcv(msqid,(void *)&buf,strlen(buf.mtext),0,0); i++; printf("%s ",buf.mtext); } msgctl(msqid,IPC_RMID,NULL); return 0; }