消息队列通信,王明学learn
消息队列通信
消息队列就是一个消息(一个结构)的链表。而一条消息则可看作一个记录,具有特定的格式。进程可以从中按照一定的规则添加新消息;另一些进程则可以从消息队列中读走消息。
每一个消息都是一个结构体:
struct msgbuf{
long mtype; //表示结构体类型,来区分不同的消息
char mtext[1]; //消息数据
};
一、函数学习
1创建消息队列
1).函数名
msgget
2).函数原型
int msgget(key_t key,int msgflg)
3).函数功能
打开或创建消息队列
4).所属头文件
<sys/types.h><sys/ipc.h><sys/msg.h>
5).返回值
成功:消息队列ID
失败:-1
6).参数说明
key:键值
msgflg:打开标志,IPC_CREAT:表明新创建一个消息队列
2从消息队列中读出数据
1).函数名
msgrcv
2).函数原型
ssize_t msgrcv(int msgqid,void *msgp,size_t msgsz,long msgtyp,int msgflg;)
3).函数功能
从消息队列中接受消息
4).所属头文件
<sys/types.h><sys/ipc.h><sys/msg.h>
5).返回值
失败;-1
成功:实际接收到消息长度
6).参数说明
msgqid:消息队列id
msgp:存放取出的消息
msgsz:期望取到消息的最大长度
msgtyp:消息的类型 0:忽略类型,直接取队列中的第一条消息
>0:取消息队列中类型等于msgtyp的第一条消息
<0:取类型比msgtyp的绝对值要小于或者等于的消息,如果有多条消息满足该条件,则取类型最小的一条
msgflg:标志
3向消息队列写信息
1).函数名
msgsnd
2).函数原型
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
3).函数功能
向消息队列发送消息
4).所属头文件
<sys/types.h><sys/ipc.h><sys/msg.h>
5).返回值
失败:-1
成功:0
6).参数说明
msqid:消息队列的的id
msgp:指向要发送的消息
msgsz:消息的长度、消息中的这个成员char mtext[1]的长度
msgflg:标志位
4删除消息队列(通过消息队列控制实现删除)
1).函数名
msgctl
2).函数原型
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
3).函数功能
控制消息队列
4).所属头文件
<sys/types.h><sys/ipc.h><sys/msg.h>
5).返回值
成功:0
失败:-1
6).参数说明
msqid:消息队列id
cmd:对消息队列执行的操作命令,IPC_EMID用于删除消息
buf:获取内核中的msqid_ds结构
二、实例学习
2.1首先编辑send.c文件
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/ipc.h>
4 #include <sys/msg.h>
5 #include <string.h>
6 struct msgt{
7 long msgtype;
8 char msgtext[1024];
9 };
10
11 int main()
12 {
13 int msqid;
14 int msg_type;
15 char str[256];
16 struct msgt msgs;
17 //创建消息队列
18 msqid = msgget(1024,IPC_CREAT);
19
20 //while
21 while(1)
22 {
23 printf("Please input message type,0 for quit!\n");
24 //获取消息类型
25 scanf("%d",&msg_type);
26
27 //如果用户输入的消息类型为0,退出该循环
28 if(!msg_type)
29 break;
30
31 //获取消息数据
32 printf("please input message content!\n");
33 scanf("%s",str);
34
35 msgs.msgtype = msg_type;
36 strcpy(msgs.msgtext,str);
37
38
39 //发送数据
40 msgsnd(msqid,&msgs,sizeof(struct msgt),0);
41 }
42
43 //删除消息队列
44 msgctl(msqid,IPC_RMID,0);
45 return 0;
46 }
2.2编辑read.c文件
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/ipc.h>
4 #include <sys/msg.h>
5 #include <string.h>
6
7 int msqid = 0;
8
9 struct msgt{
10 long msgtype;
11 char msgtext[1024];
12 };
13 int childprocess()
14 {
15 struct msgt msgs;
16 while(1)
17 {
18 //接收消息队列
19 msgrcv(msqid,&msgs,sizeof(struct msgt),0,0);
20
21 //打印消息队列中的数据
22 printf("msg text: %s\n",msgs.msgtext);
23 }
24 return 0;
25 }
26
27 int main()
28 {
29 int msqid;
30 int i;
31 int cpid;
32 //打开消息队列
33 msqid = msgget(1024,IPC_EXCL);
34
35 //创建3个子进程
36 for(i=0;i<3;i++)
37 {
38 cpid = fork();
39 if(cpid<0)
40 printf("creat child process error!\n");
41 else if(cpid ==0)
42 childprocess();
43 }
44 //
45 return 0;
46 }
2.3编译分别在两个linux终端运行两个进程