当前位置: 首页 > 编程日记 > 正文

IPC--消息队列

消息队列的特点

消息队列是生命周期是随进程的,同时消息队列可以实现的是消息的传递方向是双向的。接受者和发送者时通过发送一个数据块来进性消息传递的,每个消息的数据类型不一样依次来进行区分我们该取哪个数据。消息队列是基于消息的,并不是像管道一样基于字节流,因此我可以一次放入或者取出一个数据块,另外也不是先进先出的。但是消息队列也有一个最大的存储上限(MSGMAX)。

IPC对象 数据结构

我们可以理解,每个消息队列也是一个数据存储空间,系统 为了维护这个存储空间,定义了一个数据结构用于维护它的各种信息

struct ipc_perm {
key_t __key; /* Key supplied to xxxget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};

简单的解释其中的几个数据
__key:类似于内存描述符pc一样,__key也是一个标志某一个消息队列的唯一标识符,唯一的身份ID。
cuid:创建用户id
cgid:创建用户组id
mode:消息队列相关权限

消息队列结构(/usr/include/linux/msg.h)

struct msqid_ds
{struct ipc_perm msg_perm;     /* Ownership and permissions */time_t          msg_stime;    /* Time of last msgsnd(2) */time_t          msg_rtime;    /* Time of last msgrcv(2) */time_t          msg_ctime;    /* Time of last change */unsigned long   __msg_cbytes; /* Current number of bytes inqueue (nonstandard) */msgqnum_t       msg_qnum;     /* Current number of messagesin queue */msglen_t        msg_qbytes;   /* Maximum number of bytesallowed in queue */pid_t           msg_lspid;    /* PID of last msgsnd(2) */pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
};

我们可以看到消息队列结构中的第一个内容就是IPC数据的对象结构体,可以这样简单的理解,我们的所有的消息队列用一个队列进行维护,这个队列中就放置了很多关于消息队列的各个信息。

消息队列的创建

#include<sys/types.h>
#include<msg.h>
#include<ipc.h>
int msgget(key_t key, int msgflg);

其中的key可以理解为一个端口号,我们可以这样理解消息队列也是一个存储空间,把它比作是一个房间,而中国key就是房间的门,就是一个端口。接下来会介绍 一个函数ftok,由他来生成key。msgflg是操作消息队列的方式,有两个参数IPC_CREAT和IPC_EXCL,当我们单独的使用IPC_CREAT如果IPC不存在创建一个新的IPC,如果已经存在则打开它;通常IPC_EXCL不单独使用,我们是结合着IPC_CREAT一起使用,这样做的结果是保证所得的对象是新建的,而不是已经打开的。

程序详解

下面的这个程序,写了一个客户端一个服务端,然后利用消息队列进行进程间通信

封装函数

#include"comm.h"int commMsgQueue(int flag)   //这里封装了一个关于消息队列的一个函数,通过传入参数即IPC_CREAT和IPC_EXCL来完成创建消息队列和得到消息队列的操作,这里加上static只是想让这个函数在本文件中有效
{key_t key = ftok(".",0);   //第一个参数是路径名,第二个参数是随意给的一个,这里我如果使用的是"./queue"就错误//这里一开始写0x6666,然后错了if(key < 0){printf("ftok error\n");return -1;}int queue = msgget(key,flag);   //key是生成的一个端口,后面的两个宏时固有的参数,0666是访问 的权限if(queue == -1){printf("msgget error\n");return -2;}return queue;   //这里我开始返回值是0,,这个是错误的,应该返回的是消息队列id,因为这个id以后会用到
}int creatMsgQueue()
{int ret = commMsgQueue(IPC_CREAT|IPC_EXCL|0666);if(ret < 0){printf("creatMsgQueue error\n");return -1;}return ret;
}int getMsgQueue()
{int ret = commMsgQueue(IPC_CREAT);if(ret < 0){printf("getMsgQueue error\n");return -1;}return ret;
}int desMsgQueue(int id)
{int flag = msgctl(id,IPC_RMID,NULL);if(flag < 0){printf("delete error\n");return -1;}return 0;
}int rcvMsg(int id,int who,char* recbuf)  //我们需要得到某一个队列中的消息,所以这里传入队列号,另外我们还需要传入一个类型,这个类型是确认某一个类型呢的
{msginfo buf;    int ret = msgrcv(id,&buf,sizeof(buf.mtext),who,0);strcpy(recbuf,buf.mtext);if(ret < 0){printf("rcvMsg error\n");return -1;}return 0;
}int sndMsg(int id,int who,char* sndbuf)  //标记要往哪个队列里面发,标记发送或者是接受的数据类型,who就是相当于标记数据类型
{int  ret;msginfo buf;buf.mtype = who;  //who是用来标记数据类型 的strcpy(buf.mtext,sndbuf);  //这个时候我们应该是从外面传入一个数据//int msqid = getMsgQueue();//这里不能这样使用,因为我们要往一个消息队列中发送数据的时候,应该在外面把这个队列的id传进来//ret = msgsnd(id,(void*)&buf,sizeof(buf.mtext),0);  //虽然在这个函数中没有使用到who,但是who传进来是为了标记//上面的那个buf.mtype的    发数据的时候只需要标记自己的类型就好了,所以这个函数中并没有who选项用来标记数据的//类型,但是在上面的取数据的时候却需要who这个选项 用来识别我应该取什么样子的数据类型if(ret < 0){printf("sndMsg error\n");return -1;}return 0;
}

server

#include"comm.h"
int main()
{int id = creatMsgQueue();char  sndbuf[1024];char recbuf[1024];int i = 0;  printf("%d\n",id);
//  printf("creat queue success\n");while(i++ < 10){printf("请输入:");scanf("%s",sndbuf);//  sleep(1);//  rcvMsg(id,CLIENT,recbuf);//  printf("%s",recbuf);//sleep(1);     sndMsg(id,SERVER,sndbuf);rcvMsg(id,CLIENT,recbuf);printf("client say # %s\n",recbuf);}desMsgQueue(id);return 0;
}

client

#include"comm.h"
int main()
{
//  int id = creatMsgQueue();char  sndbuf[1024];char recbuf[1024];int i = 0;int id = getMsgQueue(); 
//  printf("creat queue success\n");while(i++ < 10){//printf("请输入:");//scanf("%s",sndbuf);//  sleep(1);//  rcvMsg(id,CLIENT,recbuf);//  printf("%s",recbuf);//sleep(1);     //sndMsg(id,CLIENT,sndbuf);rcvMsg(id,SERVER,recbuf);printf("server say # %s\n",recbuf);printf("请输入 #");scanf("%s",sndbuf);//sleep(1);sndMsg(id,CLIENT,sndbuf);}//desMsgQueue(id);return 0;
}

comm.h

#ifndef __COMM_H__
#define __COMM_H__#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include<string.h>typedef struct _msginfo{long mtype;char mtext[1024];
}msginfo;#define CLIENT 1
#define SERVER 2int getMsgQueue();
int creatMsgQueue();
int commMsgQueue(int flag);
int desMsgQueue(int id);
int commMsg();
int sndMsg(int id,int who,char* sndbuf);
int rcvMsg(int id,int who,char* recbuf);#endif

相关文章:

sqlinesdata教程_如何将Oracle数据导入MySQL

Manager进程&#xff1a;需要源端跟目标端同时运行&#xff0c;主要作用是监控管理其它进程&#xff0c;报告错误&#xff0c;分配及清理数据存储空间&#xff0c;发布阈值报告等Extract进程&#xff1a;运行在数据库源端&#xff0c;主要用于捕获数据的变化&#xff0c;负责全…

关于PHP.ini文件的设定

php.ini文件中记录了php的配置&#xff0c;因此正确读取此配置文件对于php的部署实施很重要。 windows平台中&#xff0c;有2种常用的方法。 第一种方法&#xff1a;把php.ini复制到c:\windows目录中。 第二种方法&#xff1a;配置apache服务器&#xff0c;在..\Apache Softwar…

PAT (Advanced Level) 1132~1135:1132 模拟 1133模拟(易超时!) 1134图 1135红黑树

1132 Cut Integer&#xff08;20 分&#xff09; 题意&#xff1a;将一个含K&#xff08;K为偶数&#xff09;个数字的整数Z割分为A和B两部分&#xff0c;若Z能被A*B整除&#xff0c;则输出Yes&#xff0c;否则输出No。 分析&#xff1a;当A*B为0的时候&#xff0c;不能被Z整除…

poj 1523(无向联通图的割点)

结合tarjan算法思想&#xff0c;这题终于写了出来。 同样用dfs将图变成为一颗树&#xff0c;这样可以提供许多有用的性质。 对于一个无向连通图&#xff0c;dfs后的树为只有回边&#xff08;回边Euv,v是u的祖先&#xff09;和生成树的边的图。 那么在遍历到一个点u的时候&#…

IPC--信号量

信号量概念理解 信号量本质上 是一个计数器&#xff0c;用来统计临界资源申请资源的个数。其中的二元信号量的 值是0或者是1&#xff0c;即是要么是有&#xff0c;要么是无。信号量本身也是临界资源&#xff0c;所以一定要保证其原子性。信号量的工作原理&#xff1a;两个进程…

7 自动开启网卡_淘汰的旧手机别扔掉,这样设置变身4G上网卡

很多人都用过usb无线上网卡&#xff0c;把手机SIM卡插到上网的卡槽内&#xff0c;然后把usb上网卡插到电脑usb口&#xff0c;电脑安装好驱动程序后&#xff0c;即可畅游网络世界。当初3G上网卡价格不菲&#xff0c;随着更新换代4G快要过去&#xff0c;5G开始试商用&#xff0c;…

Struts2 的stream result用法

2019独角兽企业重金招聘Python工程师标准>>> <action name"download" class"com.unmi.action.DownloadAction"> <result name"success" type"stream"><!--type 为 stream 应用 StreamResult 处理-->…

Largest Rectangle in a Histogram

ps&#xff1a;单调栈&#xff0c;注意红色部分的代码。 int n;stack<P> s;inline void upd(LL &x, LL y) { (x < y) && (x y); }int main() {while(sc(n) ! EOF && n) {while(!s.empty()) s.pop();LL ans 0;Rep(i, 1, n) {int x;sc(x);if (s.e…

IPC--共享内存

有了之前的学习经验&#xff0c;共享内存对我们学习起来相对简单一些了&#xff0c;这里简单说说共享内存的一些&#xff0c;然后对于函数的分析直接在代码里面的注释部分有说明&#xff0c;如果还是不懂&#xff0c;可以先看看前面的关于IPC–信号量还有IPC–消息队列的讲解 …

2020年行政区划代码_2020年柳州市行政区划,了解柳州市有几个区,详细数据

本文通过整理了柳州市行政区划代码数据及柳州市统计用的城乡划分代码&#xff0c;带你了解柳州市有几个区、县及下面的街道和镇划分详细情况。柳州市有几个区、县、县级市&#xff1f;答&#xff1a;柳州市有5个区、5个县(行政区划2020年7月)。分别为&#xff1a;城中区、鱼峰区…

sql2000 转sql2008

1&#xff0c;在sql2008服务器上新建空数据库&#xff0c;与sql2000同名&#xff0c;当然可以不同名。 2&#xff0c;在sql2008服务器上选择数据库&#xff0c;点右键&#xff0c;任务-导入数据。打开导入数据向导。 3&#xff0c;点击下一步&#xff0c;选择数据源。数据源可以…

linux下查看网卡型号

查看网卡型号[rootcentos /]# lspci | grep Ethernet02:01.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] (rev 10)我这里型号是79c970,驱动pcnet32.查看驱动信息[rootcentos /]# modinfo pcnet32filename: /lib/modules/2.6.18-194.el5/…

linux_域名映射

vi /etc/hosts在最后加上ip及映射的域名192.168.229.111 node001192.168.229.112 node002192.168.229.113 node003 转载于:https://www.cnblogs.com/lxyuuuuu/p/9578659.html

地址解析协议ARP

设计需求 ARP协议解决的问题就是&#xff1a;在同一个局域网中&#xff0c;解决主机IP地址和硬件地址的映射问题 基本使用原理 当数据在网络中某一条链路传输的时候我们知道目的主机的IP地址&#xff0c;但是不知道硬件地址&#xff0c;ARP协议就是解决这个问题的一个协议&a…

ie8加载js太慢_js ie8 慢

Re请教ap6214f2r版主一些问题引用第2楼ap6214f2r于2012-09-10 14:08发表的 :楼主&#xff0c;关于你说的慢&#xff0c;我去看了下你网站响应速度非常快[attachment26863]这个请求是计算签名&#xff0c;跳转到OSS的。.......老大&#xff0c;我刚才试了一下&#xff0c;不是线…

LINQ : IEnumerableT and IQueryableT区别

本地数据源计算机会自动使用IEnumberable<T>,远程数据源会使用IQueryable<T> 下面这条语句没有使用数据库里的EF数据&#xff0c;显示如下&#xff1a; 下面这条语句使用数据库里的EF数据&#xff0c;显示如下&#xff1a; 针对Linq “LINQ TO to OBJECTS”&#…

九大网络安全失误,需要注意

在我们的职业生涯中大都曾经有过一次这样的经历——我是说你认为足以让你丢掉饭碗的失误。我的第一次重大失误是曾经重启了校园里的所有路由器&#xff0c;不是一个接一个的&#xff0c;而是所有一次完成。我写了一个脚本&#xff0c;为所有的路由器安装一个安全更新&#xff0…

python学习笔记——Thread常用方法

http://blog.sina.com.cn/s/blog_4b5039210100ewie.html Thread对象中的一些方法&#xff1a; 以前说过多线程&#xff0c;用到threading模块中的Thread对象&#xff0c;其中的start和run方法比较熟悉了&#xff0c;start&#xff08;&#xff09;是重载了Thread对象中的run方法…

常见的路由选择算法

一、路由表 所谓路由表&#xff0c;指的是路由器或者其他互联网网络设备上存储的表&#xff0c;该表中存有到达特定网络终端的路径&#xff0c;在某些情况下&#xff0c;还有一些与这些路径相关的度量。 二、常见路由表生成算法 路由算法是提高路由协议功能&#xff0c;尽量…

linux 远程挂载摄像头_基于Linux的嵌入式网络摄像机设计

本嵌入式网络摄像机采用高性能ARM9芯片微处理器&#xff0c;内置嵌入式Web服务器。通过嵌入式多任务操作系统采集摄像机视频数据&#xff1b;采集的视频信号数字化后经MJPEG算法压缩&#xff0c;再通过内部总线送到内置的Web服务器&#xff1b;使用者可以直接用浏览器观看Web服…

2012 ARM嵌入式开发应用研讨会杂谈

记得以前参加的ARM的研讨会&#xff0c;名称是技术研讨会&#xff0c;不知道为什么现在改名为嵌入式开发应用研讨会了。不过今年演讲的重点就是 ARM DS-5开发工具&#xff08;还免费发放了一本《Linux/Android开发利器 ARM DS-5使用指南》书籍&#xff09;&#xff0c;也许这就…

打印不同对象的字节表示 ( 对int*强制转换成unsigned char*的理解 )

此文章参考《深入理解计算机系统》P31。 先看如下代码&#xff1a; 12345的十六进制表示为&#xff1a;0x00003039 1 #include <stdio.h>2 3 int main()4 {5 int a 12345;6 char *q (char *)(&a);7 for(int i 0; i < sizeof(a); i)8 prin…

NAT技术和代理服务器

一、代理服务器 所谓“代理”&#xff0c;就是代而劳之的意思。代理服务器就是代理网络用户去取得网络信息&#xff0c;形象的说&#xff1a;它是网络信息的中转站&#xff0c;使得一个网络终端和另一个网络终端不直接进行相连&#xff0c;代理网络用户去取得信息。主要工作在O…

链接全局变量再说BSS段的清理

废话就不多说了&#xff0c;开始。。。 再说BSS段的清算 以前遇到一个裸机程序不能改变全局变量值的问题&#xff0c;最后模模糊糊处理了&#xff1a;手动添加了一个链接脚本&#xff0c;清算了BSS段。问题得以处理&#xff0c;就认定是BSS段清算的问题&#xff0c;全局变量在B…

ios启动页尺寸_关于移动端App启动页的策划方案

App启动页是指app在启东时需要加载必要的运行环境和配置&#xff0c;在这个过程中提示用户等待的一个过渡页面。在产品经理眼里启动页是app给予用户重要的第一印象&#xff1b;也是App最重要的黄金页面之一&#xff0c;所有用户100%都会看到的页面。启动页适合用来做以下几个事…

事件流--事件冒泡现象及阻止

事件冒泡现象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>事件冒泡现象</title><style>div{padding: 50px;}#div1{background: red;}#div2{background: blue;}#div3{background: yell…

谁知道静态成员的纠结心境

我们在实际开发的过程中&#xff0c;可能需要某些类的成员变量并不是针对每一个对象的&#xff0c;而是针对每一个类而言的&#xff0c;比如在银行中有一个利率数据&#xff0c;我们希望的是&#xff0c;当一个利率改变的时候&#xff0c;所有的对象都能够看到这个改变的数据&a…

.net ConfigurationSectionDesigner插件使用

最近接触了vs2010的一款插件&#xff1a;ConfigurationSectionDesigner。ConfigurationSectionDesigner是一个图型化设计.net的配置块和自动生成需要代码和schema定义的codeplex上的一个开源项目&#xff0c;现在分享出来&#xff0c;希望对大家有所帮助。 .Net配置体系中可以是…

对应到对象 数据库驼峰_【GI的自主空间数据库】一种竞争力,叫技术引领;一种竞争力,叫时间沉淀...

引子&#xff1a;GI的自主空间数据库及GIS框架来自于求学时MAPGIS的引导&#xff0c;工作时ARCGIS的追随&#xff0c;读博时IBM和Microsoft2篇文献...。即使在大数据技术发展的今天&#xff0c;自主空间数据库存储仍然有其技术优势&#xff0c;近20年的时间沉淀&#xff0c;是G…

TSM备份Windows数据

一、备份数据 1.使用备份勾当客户端&#xff0c;可以在原始文件出现损坏的时候&#xff0c;恢复备份版本。TSM提供备份和恢复文档的类型包括:FAT&#xff0c;NTFS和FAT32.2.合适备份和合适归档文件当备份-归档客户端备份或归档一个文件&#xff0c;他会发送一份文档的副本和它的…