一种基于Linux内核的多点到多点数据发布和订阅方法

文档序号:8457188阅读:942来源:国知局
一种基于Linux内核的多点到多点数据发布和订阅方法
【技术领域】
[0001]本发明属于数据通信领域,尤其涉及在多任务操作系统环境下,任务间通信的方法。
【背景技术】
[0002]Linux操作系统是多用户、多任务操作系统,广泛应用在各种通信和电子设备上。在多任务操作系统上,多个任务并发协同工作,可有效提高硬件平台的使用效率和业务的处理能力。但是同时,多任务并发协同工作,为设计人员带来了任务间同步和任务间通信的要求。
[0003]Linux操作系统下,常用的任务间通信(IPC)方法包括信号量、管道、共享内存、消息队列和套接字(Socket),每种通信方式的特点如下:
[0004]信号量:信号量是一种异步通信机制,任务不需要执行任何操作来等待信号的到达。信号异步通知接收信号的任务发生了某个事件,然后操作系统将会中断接收到信号的任务的执行,转而去执行相应的信号处理程序。信号通知任务发生某种事件,无法传输大量数据。
[0005]管道:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的任务间使用。
[0006]共享内存(shared memory):共享内存就是映射一段能被其他任务所访问的内存,这段共享内存由一个任务创建,但多个任务都可以访问。共享内存是最快的IPC方式,它是针对其他任务间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现任务间的同步和通信。
[0007]套接字:套接字通过TCP/IP协议进行数据通信,可用于不同CPU间任务和同一个CPU上多任务之间的通{目;
[0008]消息队列:消息队列是一个消息的链表,具有特定的格式及特定的优先级,写任务可以向消息队列中写入数据,读任务可以从消息队列冲读取消息;
[0009]各种通信方式都有其特点,因此,适合在各种不同通信需要情况下使用。例如:管道只能在具有亲缘关系的任务间使用,只支持单项数据流,管道所传送的是无格式字节流,不区分消息的边界;共享内存适合任务间大数据量的交互,但是由于多个任务可以同时访问同一块内存,数据的安全性和一致性需要严密的任务间同步来保证;套接字适合不同主机任务间通信,但是对于同一主机上的任务,套接字的网络特征却成了累赘,数据的传输要经过复杂的TCP/IP协议封装,各层报头封装,CRC校验和确认等等特征都降低了通信的传输效率;消息队列效率较高,但是,同一任务无法通过异步通知模型同时访问多个消息队列,而且消息队列只支持点对点数据通信,无法实现一点对多点或者多点对多点的数据通信。

【发明内容】

[0010]本专利的目的是提出一种轻量级的、高效率的、支持异步通知模型的、多点对多点的任务间通信方法,称为多点到多点数据发布和订阅方法。
[0011]本发明通过以下技术方案来实现上述目的:一种基于Linux内核的多点到多点数据发布和订阅方法,包括以下步骤:
[0012]SliLinux系统加载内核模块,在其文件系统中生成发布文件和订阅文件,在内核中生成邮箱池;
[0013]S2: 一个或多个发布任务分别进行发布数据准备,一个或多个接收任务分别进行订阅数据准备;
[0014]S3:一个或多个发布任务分别发送数据并将数据写入Linux内核,Linux内核通知每个接收任务分别接收数据,每个接收任务分别接收并读取数据,所有的接收任务均读取数据之后,Linux内核将数据删除。
[0015]其中,步骤S2中的发布任务进行发布数据准备具体为:
[0016]S201:发布任务打开发布文件,根据发布文件在邮箱池中查找与要创建的邮箱名称相同的邮箱,若找到,则将该邮箱的地址返回给发布任务;若未找到,则执行步骤S202 ;
[0017]S202:在内核中创建以该名称命名的邮箱,将邮箱插入邮箱池,然后为邮箱创建若干报头和若干报文,在邮箱的预留空间中登记发布任务的个数和接收任务的个数,将创建的邮箱的地址返回给发布任务。
[0018]其中,步骤S2中的接收任务进行订阅数据准备具体为:
[0019]S211:接收任务打开订阅文件并生成订单,订单中包含内核等待队列;
[0020]S212:根据订阅文件在邮箱池中查找与要订阅的邮箱名称相同的邮箱,若找到,则将生成的订单保存到该邮箱中;若未找到,则执行步骤S213 ;
[0021]S213:在内核中创建以该名称命名的邮箱,将邮箱插入邮箱池,然后为邮箱创建若干报头和若干报文,在邮箱的预留空间中登记发布任务的个数和接收任务的个数,将生成的订单保存到创建的邮箱中;
[0022]S214:将订单地址返回给接收任务;
[0023]S215:接收任务通过poll函数等待在订单的内核等待队列上。
[0024]其中,在内核中创建以该名称命名的邮箱,将邮箱插入邮箱池,然后为邮箱创建若干报头和若干报文,具体为:
[0025]S221:根据邮箱的数据结构在内核中为邮箱申请内存,给邮箱命名,在邮箱中预留多个空间分别保存发布任务数量、接收任务数量、空闲报文列表、空闲报头列表和订单;
[0026]S222:将邮箱插入邮箱池;
[0027]S223:根据报文的数据结构在内核中为报文申请内存,在报文中预留多个空间分别保存报文的承载能力、承载数据后报文的大小、订单的数量和发布任务的数据;
[0028]S224:将报文插入邮箱的空闲报文列表;
[0029]S225:根据报头的数据结构在内核中为报头申请内存,在报头中预留空间保存报文;
[0030]S226:将报头插入邮箱的空闲报头列表。
[0031]其中,步骤S3中发布任务将数据写入Linux内核具体为:
[0032]S31:发布任务查找要写入数据的邮箱,根据邮箱中的订单判断是否有接收任务订阅该数据,若没有,则发送终止;若有,执行步骤S32 ;
[0033]S32:根据空闲报文列表从邮箱中获取空闲的报文,判断该报文的承载能力是否满足需求,若满足,将数据保存到该报文中;若不满足,释放该报文并获取新的报文,将数据保存到新的报文中,更新邮箱中接收任务的数量;
[0034]S33:根据邮箱中的订单数量获取空闲的报头,将添加数据后的报文分别保存到每个报头中,在每个订单中插入一个添加该报文的报头;
[0035]S34:唤醒所有订单中的内核等待队列。
[0036]其中,所述步骤S3中接收任务读取数据具体为:接收任务从订单中获取数据,每次获取数据后将报文中的接收任务数量减1,并将订单中的报头插回邮箱的空闲报头列表,当接收任务数量为O时清除报文中的数据并将报文插回邮箱的空闲报文列表。
[0037]本发明方法相对于【背景技术】的优点:
[0038](I)本方法在Linux内核中实现,以内核模块的形式存在,大量使用了双向内核消息队列,方便了数据的检索,提高了数据存储和访问的效率。
[0039](2)本发明的内核模块为用户态的任务提供了文件访问接口,任务通过打开,关闭,1ctl,读,写和Poll操作使用内核模块,实现多任务间通信。
【附图说明】
[0040]图1为本发明的所有任务初始化之后内核中的数据结构;
[0041]图2为本发明实施例发布任务A或者发布任务B发布数据报,接收任务D和接收任务E获取数据报过程中内核中的数据结构;
[0042]图3为本发明邮箱的数据结构;
[0043]图4为本发明报头的数据结构;
[0044]图5为本发明订单的数据结构;
[0045]图6为本发明报文的数据结构。
【具体实施方式】
[0046]下面结合附图和实施例对本发明做进一步详细的说明。
[0047]本文通过举例的方式描述本发明的内容和实施方式。假设应用层的发布任务为三个,接收任务为两个,分别为发布任务A、发布任务B、发布任务C、接受任务D和接受任务E。发布任务A和发布任务B同时发布的邮箱名称为“MSGQ_TEST1”,发布任务C发布的邮箱名称为“MSGQ_TEST2”,接收任务D和接收E同时订阅的邮箱名称为“MSGQ_TEST1”。
[0048]一种基于Linux内核的多点到多点数据发布和订阅方法,具体过程如下:
[0049]1.内核启动,系统自动加载内核模块:
[0050]a)在文件系统内生成“发布文件”;
[0051]b)在文件系统中生成“订阅文件”;
[0052]c)在内核中生成双向链表表头数据邮箱池,并且对邮箱池进行初始化;
[0053]2.发布任务进行发布数据准备,为发布任务A、发布任务B和发布任务C写数据创建内核资源;接收任务进行订阅数据准备,为接收任务D和接收任务E读数据的任务创建资源;
[0054](I)发布任务进行发布数据准备具体为:
[0055]a)发布任务A打开“发布文件”;
[0056]b)发布任务A调用1ctl,并进行数据发布初始化工作;
[0057]c)内核获取名称为“MSGQ_TEST1”,该数据报对应的邮箱名称为“MSGQ_TEST1” ;
[0058]d)发布任务A扫描邮箱池,如果存在名称为“MSGQ_TEST1”的邮箱,则返回该节点指针;如果不存在名称为“MSGQ_TEST1”的邮箱,则在内核中生成一个新的邮箱;
[0059]e)初始化邮箱的数据结构(邮箱的数据结构如图3所示),具体包括:
[0060]I)在邮箱的邮箱名称域保存新生成的邮箱的名称“MSGQ_TEST1”,在邮箱的发布任务数量域保存发布该数据的任务数量(初始为O),在邮箱的订单数量域保存订阅该数据的任务数量(初始为O),在邮箱消息统计域统计数据报发送次数(初始为O);
[0061]2)在邮箱中初始化三个双向链表头,分别为订单链表头、空闲报文链表头和空闲报文链表头;订单链表头用于串联所有订单的信息,空闲报文链表头链表用于串联空闲的报文,空闲报头链表头用于串联空闲的报文;
[0062]f)通过邮箱中的链表节点域将新生成的邮箱插入邮箱池链表;
[0063]g)将订单链表和空闲报文链表初始化为空链表,初始化若干报头并将其添加到空闲报头链表上,初始化报头数据结构;报头数据结构如图4所示;
[0064]初始化报头数据结构具体为:将报头的报文指针域初始化为空;
[0065]h
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1