【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列
2014-11-11 13:16
706 查看
【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列
2. 消息队列属性控制
#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
#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
需要强调的是,发送端和接收端的消息队列标识符要一致,以确保消息访问的队列一致,如果发送端和接收端消息队列不一致,则无法实现通信。
消息队列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相关文章推荐
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列 分类: Linux --- 应用程序设计 2014-11-11 13:16 71人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础 分类: Linux --- 应用程序设计 2014-11-11 13:08 51人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - exec和system函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - exec和system函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 守护进程
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - Linux常见信号及处理
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - Linux常见信号及处理 分类: Linux --- 应用程序设计 2014-11-08 11:54 68人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号量通信机制 分类: Linux --- 应用程序设计 2014-11-13 11:08 70人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 回收进程用户/内核资源
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号集与屏蔽信号 分类: Linux --- 应用程序设计 2014-11-08 13:19 53人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 等待信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 等待信号 分类: Linux --- 应用程序设计 2014-11-09 11:25 50人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号应用实例 分类: Linux --- 应用程序设计 2014-11-09 11:33 66人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 管道 分类: Linux --- 应用程序设计 2014-11-05 11:18 75人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存 分类: Linux --- 应用程序设计 2014-11-15 18:25 55人阅读 评论(0) 收藏
- 【原创】《Linux高级程序设计》杨宗德著- 进程管理与程序开发 - fork和vfork函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 孤儿进程和僵死进程