博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Linux】IPC-消息队列
阅读量:5961 次
发布时间:2019-06-19

本文共 3916 字,大约阅读时间需要 13 分钟。

问题 消息队列id 和键值KEY区别?

首先要注意一个概念:IPC结构都是内核的结构。也就是说IPC结构由内核维护,对于每个进程都是公共的,不属于某个特定进程。只有这样,IPC结构才能支持它们“进程间通信”的功能。

有两个东西可以标识一个IPC结构:标识符(ID)和键(key)。

Key是IPC结构的内部名。内部即在进程内部使用,这样的标识方法是不能支持进程间通信的。

ID就是IPC结构的外部名。这些进程得到的ID其实是标识了同一个IPC结构,如消息队列同时被进程A和进程B访问。多个进程间就可以通过这个IPC结构通信。

已知一个key,当希望利用这个key创建一个新的IPC时,可以使用get函数,并在flag中指定IPC_CREAT位,例如队列的情况,就是qid = msgget(key, IPC_CREAT)

一、基本概念

  • 消息队列就是一个消息的链表。一条消息可以看作一个有结构的记录。
  • IPC方式之一(进程间通信)
  • 消息可以通过结构类型区分

1143923-20170804213141787-372320002.jpg

二、函数学习

2.1 创建消息队列

2.1.1 函数名
msgget
2.1.2 函数原型
int msgget(key_t key, int msgflg);
2.1.3 函数功能
打开或创建消息队列
2.1.4 头文件
#include 
#include
#include
2.1.5 返回值
success:the message queue identifier(消息队列ID)error:-1

2.1.6 参数说明

key:键值msgflg:打开标志.    IPC_CREAT:标明新创建一个消息队列。                IPC_EXCL:标明打开一个消息队列

2.2 写消息

2.2.1 函数名
msgsnd
2.2.2 函数原型
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
2.2.3 功能
发送消息到消息队列
2.2.4 头文件
#include 
#include
2.2.5 返回值
success:0error:-1
2.2.6 参数说明
msqid:消息队列的IDmsgp:指向要发送的消息msgsz:消息的长度(与结构有关,不含message type)msgflg:标志位
P.S.General Form of message
struct msgbuf {           long mtype;       /* message type, must be > 0 */           char mtext[1];    /* message data */       };   The  mtext  field is an array (or other structure) whose size is speci-   fied by msgsz, a non-negative integer value.

2.3 读消息

2.3.1 函数名
msgrcv
2.3.2 函数原型
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
2.3.3 功能
从消息队列中接收消息
2.3.4 头文件
#include 
#include
#include
2.3.5 返回值
success:实际接收消息的数据长度error: -1
2.3.6 参数
msqid:消息队列的idmsgp :存放取出的消息msgsz:希望取到消息的最大长度msgtyp:消息的类型msgtyp = 0 ,忽略类型,直接取队列中的第一条msgtyp >0,  取 消息队列中类型等于msgtyp的第一条消息msgtyp <0,  取 类型比msgtyp的绝对值要小或者等于的消息,如果有多条消息满足该条件,则取类型号最小的一条。If msgtyp is less than 0, then the first message in  the  queue  with     the  lowest  type  less than or equal to the absolute value of msgtyp     will be read.msgflg:标志

2.4 删除消息队列(控制)

2.4.1 函数名
msgctl
2.4.2 函数原型
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
2.4.3 函数功能
控制消息队列
2.4.4 头文件
#include 
#include
#include
2.4.5 返回值
success:0error :-1
2.4.6 参数说明
msqid:消息队列的idcmd:操作命令,IPC_RMID 用于删除消息队列buf :获取内核中的msqid_ds 结构

三、综合实例

发送
/* Send.c*/#include 
#include
#include
#include
#include
struct msgbuf{ long msgtype; char msgtext[1024];};int main(){ int msqid; int msg_type; char str[256]; struct msgbuf msgs; /* 创建消息队列 */ msqid = msgget(1024,IPC_CREAT); while (1) { printf("Please input message type,0 for quit!\n"); /* 获取消息类型 */ scanf("%d",&msg_type); /* 如果用户输入的消息类型为0,退出该循环 */ if (msg_type == 0) break; /* 获取消息数据 */ printf("Please input message content!\n"); scanf("%s",str); msgs.msgtype = msg_type; strcpy(msgs.msgtext,str); /* 发送消息 */ msgsnd(msqid,&msgs,sizeof(struct msgbuf),0); } /* 删除消息队列 */ msgctl(msqid,IPC_RMID,0); return 0;}
接收
/* Receive.c*/#include 
//#include
#include
#include
#include
/* 多进程-子进程 */int msqid = 0;struct msgt{ long msgtype; char msgtext[1024];};/* 创建子线程 */void childprocess(){ struct msgt msgs; while(1) { /* 接收消息队列 */ msgrcv(msqid,&msgs,sizeof(struct msgt), 0, 0); /* 打印消息队列中的数据 */ printf("message text: %s\n",msgs.msgtext); } return;}void main(){ int i; int cpid; /* 打开消息队列 */ msqid = msgget(1024, IPC_EXCL); /* 创建3个子进程 */ for(i=0;i<3;i++) { cpid = fork();//创建子线程??? if (cpid<0) printf("Creat childprocess ERROR\n"); else if(cpid == 0) childprocess(); } }

转载于:https://www.cnblogs.com/Neo007/p/7287227.html

你可能感兴趣的文章
求职相关(链接,不定期更新)
查看>>
pdo 连接数据库 报错 could not find driver 解决方法
查看>>
设计模式之策略模式
查看>>
JVM介绍
查看>>
Qt中使用QToolBox实现抽屉效果
查看>>
双活数据中心建设之光大实践
查看>>
张晓辉:大众点评的分布式架构是怎样炼成的
查看>>
张军-大数据的理解与分布式进化计算方法
查看>>
关于Hibernate 查询oracle 字段为Date类型
查看>>
深入学习Java虚拟机之——垃圾收集算法与垃圾收集器
查看>>
android反编译之获得java源代码
查看>>
优盘驱动制作
查看>>
(分享)笔记C#基础知识
查看>>
resin
查看>>
PHP开发工具ZendStudio10
查看>>
wsl搭建php环境请求超时的问题解决方案
查看>>
spring基础
查看>>
微信用户名乱码问题
查看>>
dubbo spi(续)
查看>>
dubbo remoting(2)
查看>>