0%

进程间通信方式之消息队列

消息队列,是消息的链接表,存放在内核中,一个消息队列由一个标识符(即队列ID)来标识。

一、概念

      消息队列,是消息的链接表,存放在内核中,一个消息队列由一个标识符(即队列ID)来标识。

特点

  • 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
  • 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除
  • 消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取

二、实现

  1. msg-server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <unistd.h> // for close

// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"

// 消息结构
struct msg_form {
long mtype;
char mtext[256];
};

int main()
{
int msqid;
key_t key;
struct msg_form msg;

// 获取key值
if((key = ftok(MSG_FILE,'z')) < 0) {
perror("ftok error");
exit(1);
}

// 打印key值
printf("Message Queue - Server key is: %d.\n", key);

// 创建消息队列
if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) {
perror("msgget error");
exit(1);
}

// 打印消息队列ID及进程ID
printf("My msqid is: %d.\n", msqid);
printf("My pid is: %d.\n", getpid());

// 循环读取消息
for(;;)
{
msgrcv(msqid, &msg, 256, 888, 0);// 返回类型为888的第一个消息
printf("Server: receive msg.mtext is: %s.\n", msg.mtext);
printf("Server: receive msg.mtype is: %d.\n", msg.mtype);

msg.mtype = 999; // 客户端接收的消息类型
sprintf(msg.mtext, "hello, I'm server %d", getpid());
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
}
return 0;
}
  1. msg-client.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>

// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"

// 消息结构
struct msg_form {
long mtype;
char mtext[256];
};

int main()
{
int msqid;
key_t key;
struct msg_form msg;

// 获取key值
if ((key = ftok(MSG_FILE, 'z')) < 0) {
perror("ftok error");
exit(1);
}

// 打印key值
printf("Message Queue - Client key is: %d.\n", key);

// 打开消息队列
if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) {
perror("msgget error");
exit(1);
}

// 打印消息队列ID及进程ID
printf("My msqid is: %d.\n", msqid);
printf("My pid is: %d.\n", getpid());

// 添加消息,类型为888
msg.mtype = 888;
sprintf(msg.mtext, "hello, I'm client %d", getpid());
msgsnd(msqid, &msg, sizeof(msg.mtext), 0);

// 读取类型为777的消息
msgrcv(msqid, &msg, 256, 999, 0);
printf("Client: receive msg.mtext is: %s.\n", msg.mtext);
printf("Client: receive msg.mtype is: %d.\n", msg.mtype);
return 0;
}