【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列
消息队列IPC原理
消息队列数据结构struct msqid_ds
消息队列数据结构struct msg_msg
Linux消息队列管理
1. 创建消息队列
2. 消息队列属性控制
3. 发送消息到消息队列
4. 从消息队列接收消息
消息队列应用示例
1. 示例代码 - 读取消息队列基本信息
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<sys/ipc.h> #include<string.h> #include<sys/msg.h> #define BUFSIZE 128 struct msg_buf { long type; char msg[BUFSIZE]; }; int main(int argc,char *argv[]) { key_t key; int msgid; struct msg_buf msg_snd,msg_rcv; struct msginfo buf; char *ptr="helloworld"; memset(&msg_snd,'\0',sizeof(struct msg_buf)); memset(&msg_rcv,'\0',sizeof(struct msg_buf)); msg_rcv.type=1; msg_snd.type=1; memcpy(msg_snd.msg,ptr,strlen(ptr)); if((key=ftok(".",'A'))==-1) { perror("ftok"); exit(EXIT_FAILURE); } if((msgid=msgget(key,0600|IPC_CREAT))==-1) { perror("msgget"); exit(EXIT_FAILURE); } printf("msgsnd_return=%d\n",msgsnd(msgid,(void *)&msg_snd,strlen(msg_snd.msg),0)); msgctl(msgid,MSG_INFO,&buf); printf("buf.msgmax=%d\n",buf.msgmax); printf("buf.msgmnb=%d\n",buf.msgmnb); printf("buf.msgpool=%d\n",buf.msgpool); printf("buf.semmap=%d\n",buf.msgmap); printf("buf.msgmni=%d\n",buf.msgmni); printf("buf.msgssz=%d\n",buf.msgssz); printf("buf.msgtql=%d\n",buf.msgtql); printf("buf.msgseg=%u\n",buf.msgseg); printf("msgrcv_return=%d\n",msgrcv(msgid,(void *)&msg_rcv,BUFSIZE,msg_rcv.type,0)); printf("rev msg:%s\n",msg_rcv.msg); printf("msgctl_return=%d\n",msgctl(msgid,IPC_RMID,0)); }运行结果:
$ ./msg_ipc_info msgsnd_return=0 buf.msgmax=8192 buf.msgmnb=16384 buf.msgpool=2 buf.semmap=1 buf.msgmni=1736 buf.msgssz=16 buf.msgtql=10 buf.msgseg=16384 msgrcv_return=10 rev msg:helloworld msgctl_return=0
2. 使用消息队列实现实时通信
发送端:
#include<stdio.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/msg.h> #include<string.h> struct msgbuf{ int type;char ptr[0]; }; int main(int argc,char *argv[]){ key_t key;key=ftok(argv[1],100); int msgid;msgid=msgget(key,IPC_CREAT|0600); pid_t pid;pid=fork(); if(pid==0){ while(1){ printf("pls input msg to send:");char buf[128];fgets(buf,128,stdin); struct msgbuf *ptr=malloc(sizeof(struct msgbuf)+strlen(buf)+1); ptr->type=1;memcpy(ptr->ptr,buf,strlen(buf)+1); msgsnd(msgid,ptr,strlen(buf)+1,0);free(ptr); } } else{ struct msgbuf{ int type;char ptr[1024]; }; while(1){ struct msgbuf mybuf;memset(&mybuf,'\0',sizeof(mybuf)); msgrcv(msgid,&mybuf,1024,2,0); printf("recv msg:%s\n",mybuf.ptr); } } }接收端:
#include<stdio.h> #include<stdlib.h> #include<sys/ipc.h> #include<sys/msg.h> #include<string.h> struct msgbuf{ int type; char ptr[0]; }; int main(int argc,char *argv[]) { key_t key; key=ftok(argv[1],100); int msgid; msgid=msgget(key,IPC_CREAT|0600); pid_t pid; pid=fork(); if(pid==0) //send { while(1) { printf("pls input msg to send:"); char buf[128]; fgets(buf,128,stdin); struct msgbuf *ptr=malloc(sizeof(struct msgbuf)+strlen(buf)+1); ptr->type=2; //send msg type=2 memcpy(ptr->ptr,buf,strlen(buf)+1); msgsnd(msgid,ptr,strlen(buf)+1,0); free(ptr); } } else { struct msgbuf{ int type; char ptr[1024]; }; while(1) { struct msgbuf mybuf; memset(&mybuf,'\0',sizeof(mybuf)); msgrcv(msgid,&mybuf,1024,1,0); //recv msg type=2 printf("recv msg:%s\n",mybuf.ptr); } } }发送端 - 终端1,运行结果:
$ ./msg_sender_example pls input msg to send:123 pls input msg to send:456 pls input msg to send:789 pls input msg to send:1234 pls input msg to send:接收端 - 终端2 - 运行结果:
$ ./msg_receiver_example recv msg:123 recv msg:456 recv msg:789 recv msg:1234
发送端 - 终端1,运行结果:
pls input msg to send:abc pls input msg to send:def pls input msg to send:ghi pls input msg to send:klm接收端 - 终端2 - 运行结果:
recv msg:abc recv msg:def recv msg:ghi recv msg:klm
需要强调的是,发送端和接收端的消息队列标识符要一致,以确保消息访问的队列一致,如果发送端和接收端消息队列不一致,则无法实现通信。
原文链接:
http://blog.csdn.net/geng823/article/details/41010115