消息队列类型有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 msgbuf 2 { 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 128 18 19 struct msgbuf 20 { 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 = my 52 //接收服务端消息 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 ",myrcvbuf.mtext); 58 } 59 } 60 else if(pid > 0) 61 { 62 mysndbuf.mtype = 100; 63 //客户端发送信息 64 while(1) 65 { 66 printf("please input data: "); 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 128 18 struct msgbuf 19 { 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: "); 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 ",myrcvbuf.mtext); 67 } 68 } 69 //删除消息队列 70 msgctl(msqid,IPC_RMID,NULL); 71 return 0; 72 }