消息队列提供进程间数据块传输的方法,传输的每一个数据块都认为是有类型的,不同的数据块是有优先级的;
系统中可能有很多的msgqueue, 每个MQ用消息队列描述符(消息队列ID: qid) 来区分,qid是唯一 的,用来区分不同的MQ。
消息队列中的数据都是先进先出的,整个队列中的数据是用链表组织起来的。
消息队列的每一个元素都是有类型的,用类型可以区分不同的消息,可以按照消息类型先进先出,也可以按照原本队列的顺序先进先出
int msgget(key_t key, int msgflg);
功能:以特定的消息队列标识符创建一个消息队列,并返回消息队列的操作句柄
头文件:sys/types.h、sys/ipc.h、sys/msg.h
参数:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
ssize_t msgrcv(int msqid, void *msgp, sizet msgsz, long msgtyp, int msgflg)
头文件:sys/types.h、sys/ipc.h、sys/msg.h
参数:
msgtyp | 解释 |
---|---|
msgtyp = 0 | 读取队列中的第一条消息,就相当于不区分类型,按照插入的顺序,先进先出 |
msgtyp > 0 | 读取队列中类型为msgtyp 的第一条消息,除非在msgflg中指定了MSG_ EXCEPT, 否则将读取类型不等于msgtyp的第一条消息 |
msgtyp < 0 | 读取队列中类型小于或等于msgtyp 绝对值的第一条消息 |
返回值:
int msgctl(int msqid, int cmd, struct msqid_ ds *buf);
参数:
返回值:
从消息队列中拿数据和从共享内存中拿数据不一样,是直接取走数据,不是拷贝走
往消息队列中发送消息:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/msg.h>
4 struct Msgbuf{
5 long mtype;
6 char mtext[255];
7 };
8 int main(){
9 /*
10 * 目的:往消息队列当中发送消息
11 *
12 * 做法:
13 * 1. 创建消息队列
14 * 2. 组织要发送的消息,并且发送出去
15 * 1 : send msg1
16 * 2 : send msg2
17 * 3 : send msg3
18 * 4 : send msg4
19 * ...
20 * */
21 int qid = msgget(0x78787878, IPC_CREAT | 0664);
22 if(qid < 0){
23 perror("msgget");
24 return 0;
25 }
26
27 for(int i = 0; i < 10; i++){
28 //i [0, 9]
29 struct Msgbuf mb;
30 mb.mtype = i;
31 snprintf(mb.mtext, sizeof(mb.mtext), "send msg%d", i);
32 msgsnd(qid, &mb, sizeof(mb.mtext), 0);
33 }
34 return 0;
35 }
从发送队列中接收消息:
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <sys/msg.h>
4
5 struct Msgbuf{
6 long mtype;
7 char mtext[255];
8 };
9
10 int main(){
11 /*
12 * 目的:从消息队列当中获取消息
13 *
14 * 做法:
15 * 1. 获取或者创建消息队列
16 * 2. 调用msgrecv函数进行获取消息
17 * 3. 打印获取到的消息内容
18 * send msg1
19 * send msg2
20 * ....
21 *
22 * 4 : send msg4
23 * */
24 int qid = msgget(0x78787878, IPC_CREAT | 0664);
25 if(qid < 0){
26 perror("msgget");
27 return 0;
28 }
29 struct Msgbuf mb;
30
31 msgrcv(qid, &mb, sizeof(mb.mtext), 5, 0); // send msg5
32 printf("%s\n", mb.mtext);
33 msgrcv(qid, &mb, sizeof(mb.mtext), 6, 0); // send msg6
34 printf("%s\n", mb.mtext);
35 msgrcv(qid, &mb, sizeof(mb.mtext), 7, 0); // send msg7
36 printf("%s\n", mb.mtext);
37 return 0;
38 }
执行结果:
ipcrm -q [qid] 可删除消息队列
消息队列的生命周期跟随操作系统内核