一种基于共享内存的消息总线设计与实现

2017-09-20 06:15王欣然过其峰杨建旭
电子科技 2017年9期
关键词:共享内存链表线程

王 皓,王欣然,过其峰,李 宇,杨建旭

(1.南瑞集团公司 国网电力科学研究院,江苏 南京 211106;2.安徽南瑞继远电网技术有限公司,安徽 合肥 230088)

一种基于共享内存的消息总线设计与实现

王 皓1,2,王欣然1,2,过其峰2,李 宇1,2,杨建旭1,2

(1.南瑞集团公司 国网电力科学研究院,江苏 南京 211106;2.安徽南瑞继远电网技术有限公司,安徽 合肥 230088)

针对现代数据信息通信方式中管道通信和Socket通信存在易阻塞和效率低的问题,文中利用共享内存空间原理,开辟由FRAG碎片和Block组成的缓冲池,设计了基于共享内存的消息总线通信方式。实验结果表明,该消息总线满足了数据信息通信中数据信息传递快速高效的要求,并具有较强的自适应能力。

共享内存;消息总线;Block;FRAG碎片

管道通信即发送进程以字符流形式将大量数据送入管道,接收进程可从管道接收数据;Socket通信是网络通信中的一种,这两种通信方式是目前运用最普遍的两种。但他们共存的问题就是易阻塞和效率低的问题,为此本文参考多方资料[1-6],尝试将共享内存与消息总线相结合解决上述问题。

消息总线通信方式的问题在于网络通信中不同机器紧密耦合、配置和引用混乱、服务调用关系错综复杂、难以统一管理、异构系统之间存在不兼容。本文将共享内存空间的原理结合起来,开辟了一块由FRAG碎片和Block组成的缓冲池,提出了一种基于共享内存的消息总线设计。这种设计结果表明该通信方式可以避免消息总线本身的缺点,在通信成功率和通信延迟时间方面有较大改进,具有广阔的应用前景。

1 设计需求

数据信息通信关键在于传递数据信息,无论是管道通信、Socket通信还是消息总线通信方式[7]都要为了这一目的服务。本系统正是基于这一目标而实现同一台主机系统内两个进程通过消息总线子功能共享内存完成通信;不同主机系统内两个进程通过消息总线子功能TCP、UDP实现通信;同时实现进程信息的注册、进程发送和接收消息的接口设计;并且要克服管道、Socket通信中存在的易阻塞和传输效率低等问题,从而做到通信最优化。

2 消息总线设计关键点

2.1 消息总线结构

消息总线结构如图1所示。其中结构设计流程[8]首先根据目标主机名获得相应的主机数量和编号;再创建消息,判断是本机通信还是异机通信并根据消息类型选择发送方式;接着将消息写入进程接收链表;然后读取进程接收链表;最后如果是异机通信则跟每个主机建立一个虚拟进程,通过TCP连接完成发送和接收消息。

图1 消息总线结构图

2.2 数据流向

图2 本机数据流向图

本机内两个进程间的通信主要是将数据消息通过接收链表内存的转存方式完成的。异机数据流向如图3所示。

图3 异机数据流向图

如图3所示,系统内异机间两个进程主要通过消息总线子功能TCP、UDP方式来实现通信。

2.3 消息服务管理进程设计

消息服务管理进程的设计分为:(1)处理本机消息包括巡检已注册进程(需要处理消息的进程必须向消息总线[9]进行注册)、本机进程间消息发送和接收;(2)异机间消息发送和接收线程(通过建立TCP实现);(3)异机间消息服务链路管理(通过UDP发送和处理广播报文)。

2.4 接口设计

接口设计主要包括:注册接口—通过类实例完成注册,通过注册使消息总线保存了该进程的ID;消息发送接口—标定发送类型、消息类型、目标进程、数据体、数据长度几个主要参数;消息接收接口—标定消息头和消息数据体两个参数;消息订阅接口—应用进程向消息管理进行订阅,只接收特定的消息;消息取消订阅接口—应用进程向消息管理进行订阅取消,取消已注册的接收消息类型。

柳红不响。苏秋琴说:“你担心什么呢?白天明敢在城里找野女人,我就敢给他戴绿帽子;再说在城里你只要掰掰大腿就是钱,钱来得不要太容易呵。”

2.5 共享内存设计

为解决网络通信时的消息易阻塞问题,本文在消息总线的共享内存设计中添加缓冲池设计。缓冲池[10]开辟了服务端10 MB和客户端5 MB共享内存空间,并完成共享内存的操作指针指向特定内存块及操作指针和信号量的对应,在创建时生成。共享内存的分配如图4所示。

图4 共享内存分配图

再把缓冲池分为多个Block,大小为4 096 Byte,并给缓冲池指定一个起始地址,进而每个Block的起始地址已知。每个Block又分为11个不同种类的FRAG碎片,每种碎片的大小可分为2、4、…、2 048 Byte等类型,每个FRAG碎片的地址通过链表串联起来,且第一个FRAG碎片的首地址指向该Block的起始地址,最后一个FRAG碎片[11]的尾地址指向空。Block中FRAG数据的写入过程如图5所示。

图5 Block中FRAG数据写入图

每个Block里面初始化的FRAG碎片类型与存储在该Block的第一个消息长度有关,如果一个种类FRAG的Block存储已满,则开辟下一个相应种类FRAG的Block,Block间按顺序开辟,这里开辟重点是根据消息长度初始化特定FRAG类型的链表[12],同时将该FRAG的链表连接于已有FRAG链表中,即每种FRAG碎片只有一个双向链表。

如果Block已利用完,则报错提示缓冲池已没有空间,新的消息不存储进缓冲池。每个Block里的FARG消息被取走后,更新该Block下的链表,只更新链表的前后指针,同时更新下个消息写入指针到链表下空FRAG里,如图6所示。

封装后的消息根据大小存储在对应Block的FRAG里,对应的FRAG地址返回给对应进程下的rlist链表保存。发送的原始消息经过压缩后再封装成传送的消息结构体,到接收端再解压为原始消息。FRAG的消息有3种方式被更新,第一种是被读取;第二种是超时(5 min内);第三种是进程退出,则进程下的rlist执行的FRAG被更新。

图6 Block内数据块更新图

3 消息总线设计方案实现

该设计方案实现,主要包括消息总线初始化、进程消息管理模块、进程管理模块、消息服务广播模块(UDP的发送和接收线程)、消息服务TCP功能模块(TCP的发送和接收线程)等模块功能的设计实现。

3.1 初始化共享内存

初始化共享内存分为6步依次是先计算初始化内存长度,包括系统服务信息,管理多个主机信息,管理主机内多个进程信息;再根据指定长度初始化内存块,返回对应内存ID;然后把内存ID映射到某一指针;接着创建内存操作向量;再次把内存内存块信息分别映射到具体操作指针上;最后初始化消息服务参数内存信息和主机参数。

3.2 进程消息管理模块

进程消息管理模块实现依次分3步:

(1)进程注册。包括初始化进程参数内存信息以及注册本机进程名和ID;

(2)进程消息发送接口。先判断传入的参数是否正确有效;再根据源主机名和消息发送类型查找目标客户端主机;然后根据传入的发送类型、消息类型、目标进程、数据结构体等参数创建消息结构体;最后根据目标进程ID是否在本机,确定是发送本机对应的目标还是存储到待网络发送数据区;

(3)进程消息接收接口。先检查进程是否为当前进程且是否有可读消息数;再读取接收列表的最新值;最后把读取过的消息删除,同时接收列表移动到下一个。

3.3 进程管理模块

实现进程管理需要创建两个线程—侦测线程和任务调度:

(1)侦测线程模块实现两个功能分别是通过轮询检查注册进程处理的信息是否在规定的时间内(1 min)被处理和通过系统函数检查注册进程是否在线。侦测线程模块实现方式依次为先检查进程是否在用;再判断消息是否接收超时;最后5 s扫描一次,检查进程是否存在,不存在重置进程参数,存在就不处理;

(2)任务调度模块为轮询发送的消息,判断目标主机是否在本机。

任务调度模块[13]实现方式有两步:先轮询主机列表信息;再判断消息发送目的。再根据目的的不同分为3种调度方式:第一是根据消息类型是否为广播类型,是的则归为广播消息,全系统内都发;第二是判断是否为本机进程,是本机进程则直接存储到相应进程接收列表;第三是如果非本机目标进程则存储到指定进程下的发送列表。

3.4 消息服务广播模块

消息服务广播模块的实现主要依靠创建两个线程:接收线程实现接收心跳包和其它广播报文,并存储到本地消息接收区;发送线程实现发送心跳包和其它广播报文,如图7所示。

图7 消息服务广播

3.5 消息服务TCP模块

异机通信中用到的TCP模块[14]实现也需要创建接收线程和发送调度两个线程,接收线程实现接收消息,并存储到本地消息接收区;发送线程实现发送消息;监听线程为TCP服务端实现监听连接。如图8所示。

图8 消息服务TCP模块

4 实验结果及分析

为更好的体现这种基于共享内存的消息总线通信方式的在效率和阻塞问题上的优越性,本文应用MFC框架编写了消息总线测试程序,如图9所示。上面的DOS界面是消息总线程序,下面两个MFC程序依次是测试发送进程和测试接收进程。

图9 消息总线测试程序收发进程

分别在无压力和有压力的测试环境下对消息总线进行了1 000次实验,记录3种通信方式在相同条件下的通信成功次数和平均延迟时间,数据如表1和表2所示。

表1 无压力环境3种通信方式对比

表2 有压力环境3种通信方式对比

如表1所示,在无压力测试环境下,消息总线通信方式的通信成功率达到了98.5%高于其余两种通信方式,并且平均延迟时间只有121 ms也是三者中最低的;如表2所示,在有压力测试环境下,3种测试方式的通信成功次数都有下降但消息总线通信方式的通信成功率97.7%依然是最高的,且其余两种通信方式的平均延迟时间也比消息总线通信方式的146 ms要多。综上所述,在传输效率和速度两方面消息总线通信方式较其他两种通信方式具有优越性,且消息总线对通信异常的处理更高效、更安全,具有较强的自适应性。

5 结束语

本文针对管道、Socket通信方式具有易阻塞、效率低及安全性差等缺点,将共享内存与消息总线结合起来,开辟了由FRAG碎片和Block组成的缓冲池,设计了基于共享内存的消息总线通信方式,利用共享内存可以解决消息总线不同机器之间紧密耦合、配置和引用混乱、服务调用关系错综复杂、难以统一管理、异构系统之间存在不兼容的问题,实现了总线则作为中枢系统,提供了统一的服务入口,满足了信息通信中数据信息传递快速高效的要求。并且编写测试程序对消息总线进行测试,通过结果表明该消息总线在信息传输的高效性问题上要高于另外两种通信方式,同时传输方式也具有较强的自适应能力,市场应用前景广阔。

[1] Noh D H, Kim D S. Message scheduling on CAN bus for large-scaled ship engine systems[J].IFAC Proceedings Volumes,2014(3):473-479.

[2] Sridi M, Raffin B, Faucher V. Cache aware dynamics data layout for efficient shared memory parallelisation of EUROPLEXUS [J]. Procedia Computer Science, 2016, 80(2):1083-1092.

[3] 王健,丁学明,董新燕.基于量子策略的布谷鸟搜索算法研究[J].电子科技,2015,28(12):40-44.

[4] 高念高,顾国强.一种多源异构电子政务系统整合模型[J].计算机应用与软件,2013(10):96-98.

[5] 刘虎球,赵鹏.一种多核间内存公平调度模型[J].计算机学报,2013(11):2191-2199.

[6] 苗乾坤.面向共享存储系统的计算模型及性能优化[D].合肥:中国科学技术大学,2012.

[7] 王见强.基于Web的风电SCADA系统数据服务的研究与实现[D].南京:东南大学,2015.

[8] Chen Licheng,Chen Mingyu,Yuan Ruan,et al.MIMS:towards a message interface based memory system[J].Journal of Computer Science and Technology,2014(7):292-297.

[9] Anonymous.Mission services evol-ution center message bus[J].NASA Technology Briefs,2011(8):351-358.

[10] 王伯天.基于ACE框架的并发消息总线的研究与设计[D]. 北京:北京邮电大学,2012.

[11] 余翔湛,殷丽华.动态共享内存缓冲池技术[J].哈尔滨工业大学学报,2014(3):380-383.

[12] 李小龙,孟李林,邵瑞瑞,等.基于FPGA的PCI Express应用平台设计[J].电子科技,2014,27(12):108-111.

[13] 苏勇,曹政,刘飞龙,等.一种低开销的面向节点内互连的网络接口控制器[J].计算机学报,2015(5):909-922.

[14] 崔登士.基于ACE框架的并发消息总线服务器子系统研究与实现[D].武汉:华中科技大学,2014.

[15] 辛利斌,张振国,王顺平,等.自动指纹识别系统算法的优化改良[J].电子科技,2016,29(6):41-43.

Design and Implementation of A Kind of Message Bus Based on Shared Memory

WANG Hao1,2,WANG Xinran1,2,GUO Qifeng2, LI Yu1,2, YANG Jianxu1,2

(1.NARI Group Corporation, Nanjing 210003,China;2.Anhui NARI Jiyuan Electric Co, Ltd,Hefei 230088,China)

Among current data communication modes, pipeline communication and socket communication are easy to be blocked. What’s worse, their efficiency are low. In this regard, according to the principle of shared memory, this paper develops a buffer pool consisted of fragments and blocks and designs a message bus communication mode based on shared memory. The design result indicates that the message bus faciliates quick and efficient data transfer in data communication and has strong self-adaptability.

shared memory;message bus;Block;FRAG fragment

2016- 11- 14

王皓(1970-),男,正高级工程师。研究方向:电力系统调度自动化以及继电保护。王欣然(1986-),男,经济师。研究方向:电力新技术应用。

10.16180/j.cnki.issn1007-7820.2017.09.026

TN915;TP311.1

A

1007-7820(2017)09-093-04

猜你喜欢
共享内存链表线程
基于C#线程实验探究
基于国产化环境的线程池模型研究与实现
通过QT实现进程间的通信
基于二进制链表的粗糙集属性约简
跟麦咭学编程
基于Linux内核的文件服务器模型的研究与构建
基于MTF规则的非阻塞自组织链表
基于PCI总线的多处理器协同机制研究
浅谈linux多线程协作
C++的基于函数模板实现单向链表