1.创建消息队列
demo_3.c
1 #include <sys/types.h>
2 #include <sys/ipc.h>
3 #include <sys/msg.h>
4 #include <stdio.h>
5
6 #if 0
7 int msgget(key_t key, int msgflg);
8 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
9 如果键值对应的消息队列存在,直接返回消息队列的标识符
10 参数:
11 key: 键值
12 msgflg: 设置标志,IPC_CREAT|0777
13 返回值:成功返回消息队列的标识符,出错返回-1
14 #endif
15
16 int main()
17 {
18 int msg_id;
19
20 msg_id = msgget(0x100, IPC_CREAT | 0777);
21 if (msg_id < 0)
22 {
23 perror("msgget");
24 return -1;
25 }
26
27 printf("消息队列创建成功!\n");
28 return 0;
29 }
通过int msgget(key_t key, int msgflg)函数创建消息队列,成功返回消息队列的标识符,出错返回-1;
运行demo_3.c可以看到消息队列创建成功,用ipcs指令也可查看;
2.发送消息
demo_4.c
1 #include <sys/types.h>
2 #include <sys/ipc.h>
3 #include <sys/msg.h>
4 #include <stdio.h>
5 #include <string.h>
6
7 #if 0
8 int msgget(key_t key, int msgflg);
9 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
10 如果键值对应的消息队列存在,直接返回消息队列的标识符
11 参数:
12 key: 键值
13 msgflg: 设置标志,IPC_CREAT|0777
14 返回值:成功返回消息队列的标识符,出错返回-1
15
16
17 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
18 功能:向消息队列中发送消息
19 参数:
20 msqid:消息队列的标识符
21 msgp:传入参数,打包消息基本信息内存的起始地址
22 msgsz:消息内容的大小
23 msgflg:设置阻塞标志,0表示阻塞,IPC_NOWAIT表示非阻塞
24 返回值:成功返回,出错返回-1
25
26 打包消息信息的结构体格式如下:
27 struct msgbuf {
28 long mtype; /*message type, must be > 0*/
29 char mtext[1]; /*message data*/
30 };
31 #endif
32
33 struct msgbuf {
34 long mtype;
35 char mtext[1024];
36 };
37
38 int main()
39 {
40 int msg_id;
41
42 msg_id = msgget(0x100, IPC_CREAT | 0777);
43 if (msg_id < 0)
44 {
45 perror("msgget");
46 return -1;
47 }
48
49 printf("消息队列创建成功!\n");
50
51 int ret;
52 struct msgbuf mb = {5, "hello"};
53 ret = msgsnd(msg_id, &mb, strlen(mb.mtext), 0);
54 if (ret < 0) {
55 perror("msgsnd");
56 return -1;
57 }
58 printf("消息发送成功!\n");
59
60 return 0;
61 }
通过int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)函数向消息队列中发送消息;
消息类型是5,消息内容是“hello”;
运行demo_4.c可以看到消息发送成功,用ipcs可以看到发过去1条消息,字节数为5;
往里面又写了一条重复的,然后写了一条“xiao lan”;所以消息队列里有:两个hello,一个xiao lan;
3.接受消息
demo_5.c
1 #include <sys/types.h>
2 #include <sys/ipc.h>
3 #include <sys/msg.h>
4 #include <stdio.h>
5 #include <string.h>
6
7 #if 0
8 int msgget(key_t key, int msgflg);
9 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
10 如果键值对应的消息队列存在,直接返回消息队列的标识符
11 参数:
12 key: 键值
13 msgflg: 设置标志,IPC_CREAT|0777
14 返回值:成功返回消息队列的标识符,出错返回-1
15
16
17 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
18 功能:向消息队列中发送消息
19 参数:
20 msqid:消息队列的标识符
21 msgp:传入参数,打包消息基本信息内存的起始地址
22 msgsz:消息内容的大小
23 msgflg:设置阻塞标志,0表示阻塞,IPC_NOWAIT表示非阻塞
24 返回值:成功返回,出错返回-1
25
26 打包消息信息的结构体格式如下:
27 struct msgbuf {
28 long mtype; /*message type, must be > 0*/
29 char mtext[1]; /*message data*/
30 };
31
32
33 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
34
35 功能:从消息队列中读取消息
36 参数:
37 msqid:消息队列的标识符
38 msgp:传出参数,返回消息的基本信息
39 msgsz:消息内容的大小
40 msgtyp:指定消息的类型
41 0:默认读取第一个消息
42 >0:从队头开始,读取第一个指定类型的消息
43 msgflg:设置阻塞标志
44 0:表示阻塞
45 IPC_NOWAIT:表示非阻塞
46 返回值:成功返回实际读到的字节数,出错返回-1。
47 #endif
48
49 struct msgbuf {
50 long mtype;
51 char mtext[1024];
52 };
53
54 int main()
55 {
56 int msg_id;
57
58 msg_id = msgget(0x100, IPC_CREAT | 0777);
59 if (msg_id < 0)
60 {
61 perror("msgget");
62 return -1;
63 }
64
65 printf("消息队列创建成功!\n");
66
67 int ret;
68 struct msgbuf mb;
69 ret = msgrcv(msg_id, &mb, 1024, 0, 0);
70 if (ret < 0) {
71 perror("msgrcv");
72 return -1;
73 }
74
75 mb.mtext[ret] = '\0';
76 printf("recv msg: %ld|%s\n", mb.mtype, mb.mtext);
77
78 return 0;
79 }
通过ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)函数从消息队列中读取消息;
第四个参数为0是默认读第一条消息;
运行demo_5.c,读出来一条“hello”,同时用ipcs可以看到消息队列被读走一条消息;
我之前写了一个消息类型2的“xiao lan”;
demo_5.c里改成读消息类型为2的;
运行demo_5.c,消息类型2的“xiao lan”被读出来了;
demo_6.c
1 #include <sys/types.h>
2 #include <sys/ipc.h>
3 #include <sys/msg.h>
4 #include <stdio.h>
5
6 #if 0
7 int msgget(key_t key, int msgflg);
8 功能:如果键值对应的消息队列不存在,根据第二参数的权限创建消息队列,返回消息队列的标识符
9 如果键值对应的消息队列存在,直接返回消息队列的标识符
10 参数:
11 key: 键值
12 msgflg: 设置标志,IPC_CREAT|0777
13 返回值:成功返回消息队列的标识符,出错返回-1
14 #endif
15
16 int main()
17 {
18 int msg_id;
19
20 msg_id = msgget(0x100, IPC_CREAT | 0777);
21 if (msg_id < 0)
22 {
23 perror("msgget");
24 return -1;
25 }
26
27 printf("消息队列创建成功!\n");
28
29 msgctl(msg_id, IPC_RMID, NULL);
30
31 return 0;
32 }
msgctl(msg_id, IPC_RMID, NULL);这个函数主要用来删除队列;
运行demo_6.c后,消息队列消息都被清空了;
也可以使用ipcrm -Q 键值来清空。