消息队列类型有POSLX消息队列和V系统消息队列。其中POSLX为可移植的操作系统接口。
头文件:#include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h>
A:打开/创建消息队列
int msgget(key_t key,int msgflg)
1、key:键值,由ftok获得
2、msgflg:标识位
成功返回消息队列的描述符,失败-1。
B:发送消息
int msgsnd(int msqid,struct msgbuf *msgp,int msgz,int msgflg)
1、msqid:由msgget返回的描述符
2、msgp:存放消息队列的结构
struct msgbuf 最好使用结构体,不要使用指针,容易出现段错误。
1 struct msgbuf2 {3 long mtype; /* message type, must be > 0 */4 char mtext[MAX_SIZE]; /* message data */5 };
3、msgz:消息数据的长度
4、msgflg:标识符
C:接收消息
int msgrcv(int msqid,struct mybuf *msgp,int msgz,long mtype,int msgflg)
1,msgqid:由msgget返回的描述符
2、msgp:存放消息队列的结构
3、msgz:接收消息的长度
4、mtype:消息队列的类型
5、msgflg:标识位
D:删除消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
例子:两个进程通过消息队列相互发送数据
server.c
1 /************************************************************************* 2 > File Name: shmserver.c 3 > Author: xu 4 > Mail: eeexu123@163.com 5 > Created Time: 2016年10月11日 星期二 13时40分05秒 6 ************************************************************************/ 7 8 #include<stdio.h> 9 #include<unistd.h>10 #include<stdlib.h>11 #include<string.h>12 #include<sys/types.h>13 #include<sys/ipc.h>14 #include<sys/msg.h>15 #include<sys/stat.h>16 #include<fcntl.h>17 #define MAX_SIZE 12818 19 struct msgbuf20 {21 long mtype; /* message type, must be > 0 */22 char mtext[MAX_SIZE]; /* message data */23 };24 25 int main()26 {27 key_t key;28 pid_t pid;29 int msqid;30 struct msgbuf mysndbuf,myrcvbuf;31 32 33 //创建键值34 key = ftok("./t.c",'b');35 if(key < 0)36 {37 perror("ftok");38 exit(1);39 }40 //创建消息队列41 msqid = msgget(key,IPC_CREAT|S_IRWXU);42 if(msqid < 0)43 {44 perror("msgget");45 exit(1);46 }47 //创建父子进程48 pid = fork();49 if(pid == 0)50 {51 type = my52 //接收服务端消息53 while(1)54 {55 memset(myrcvbuf.mtext,0,MAX_SIZE);56 msgrcv(msqid,(void *)&myrcvbuf,MAX_SIZE,200,0);57 printf("he massages queue data:%s\n",myrcvbuf.mtext);58 }59 }60 else if(pid > 0)61 {62 mysndbuf.mtype = 100;63 //客户端发送信息64 while(1)65 { 66 printf("please input data:\n");67 fgets(mysndbuf.mtext,MAX_SIZE,stdin);68 msgsnd(msqid,(void *)&mysndbuf,sizeof(mysndbuf.mtext),0);69 } 70 }71 //删除消息队列72 msgctl(msqid,IPC_RMID,NULL);73 return 0;74 }
client.c
1 /************************************************************************* 2 > File Name: shmclient.c 3 > Author: xu 4 > Mail: eeexu123@163.com 5 > Created Time: 2016年10月11日 星期二 13时40分14秒 6 ************************************************************************/ 7 8 #include<stdio.h> 9 #include<unistd.h>10 #include<stdlib.h>11 #include<string.h>12 #include<sys/types.h>13 #include<sys/ipc.h>14 #include<sys/msg.h>15 #include<sys/stat.h>16 #include<fcntl.h>17 #define MAX_SIZE 12818 struct msgbuf19 {20 long mtype; /* message type, must be > 0 */21 char mtext[MAX_SIZE]; /* message data */22 };23 24 int main()25 {26 key_t key;27 pid_t pid;28 int msqid;29 struct msgbuf mysndbuf,myrcvbuf;30 31 32 //创建键值33 key = ftok("./t.c",'b');34 if(key < 0)35 {36 perror("ftok");37 exit(1);38 }39 //创建消息队列40 msqid = msgget(key,IPC_CREAT|S_IRWXU);41 if(msqid < 0)42 {43 perror("msgget");44 exit(1);45 }46 //创建父子进程47 pid = fork();48 if(pid == 0) //此为子进程49 {50 mysndbuf.mtype = 200;51 //服务端发送信息52 while(1)53 {54 printf("please input data:\n");55 fgets(mysndbuf.mtext,MAX_SIZE,stdin);56 msgsnd(msqid,(void *)&mysndbuf,sizeof(mysndbuf.mtext),0);57 } 58 }59 else if(pid > 0)60 {61 //接收客户端消息62 while(1)63 {64 memset(myrcvbuf.mtext,0,MAX_SIZE);65 msgrcv(msqid,(void *)&myrcvbuf,MAX_SIZE,100,0);66 printf("he massages queue data:%s\n",myrcvbuf.mtext);67 }68 }69 //删除消息队列70 msgctl(msqid,IPC_RMID,NULL);71 return 0;72 }