发明内容
本发明实施例提供了一种进程间通信的方法以及相关装置,用于解决现有技术中父子进程通信内容不可靠的问题。
本发明实施例的第一方面提供了一种进程间通信的方法,包括:在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。
在一种可能的实施例中,所述获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存包括:
通过函数randomAccessFile.getChannel()获得所述共享文件对应的文件管道,所述randomAccessFile为用于支持读写随机存取文件的类;将所述文件管道作为函数MappedByteBufferWrap()的输入,以获得所述共享内存。
在一种可能的实施例中,所述对所述消息进行序列化处理,以在所述共享文件中组成完整的消息包括:通过函数jdkSerializable()实现所述消息的序列化;通过函数putInt()获得所述消息的长度,并根据put()函数在所述共享文件中组成完整的消息。
在一种可能的实施例中,所述方法还包括:通过函数trylock()获取所述共享文件的文件锁,所述文件锁用于避免所述一个守护进程和多个施压子进程之间的资源冲突。
在一种可能的实施例中,所述将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段包括:通过函数mMappedByteBuffer.position()和mMappedByteBuffer.put()将所述消息写入所述共享文件中;将所述共享内存的写索引字段和所述消息的长度的和作为函数setWriteIndex()的输入,以更新所述共享内存的写索引字段。
在一种可能的实施例中,所述方法还包括:当所述守护进程读取所述消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
在一种可能的实施例中,所述对所述共享文件进行压缩并过滤掉所述守护进程读取的字节包括:通过函数compact()对所述共享文件进行压缩;将所述共享内存的写索引字段和目标数组的长度的差作为函数setWriteIndex()的输入,以过滤所述读取的字节,所述目标数组用于所述守护进程读取所述消息。
本发明实施例的第二方面提供了一种通信装置,包括:创建单元,用于在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;获得单元,用于获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;处理单元,用于当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;写入单元,用于将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。
在一种可能的实施例中,所述处理单元具体用于,通过函数randomAccessFile.getChannel()获得所述共享文件对应的文件管道,所述randomAccessFile为用于支持读写随机存取文件的类;将所述文件管道作为函数MappedByteBufferWrap()的输入,以获得所述共享内存。
在一种可能的实施例中,所述处理单元具体用于:通过函数jdkSerializable()实现所述消息的序列化;通过函数putInt()获得所述消息的长度,并根据put()函数在所述共享文件中组成完整的消息。
在一种可能的实施例中,所述获得单元还用于:通过函数trylock()获取所述共享文件的文件锁,所述文件锁用于避免所述一个守护进程和多个施压子进程之间的资源冲突。
在一种可能的实施例中,所述写入单元具体用于:通过函数mMappedByteBuffer.position()和mMappedByteBuffer.put()将所述消息写入所述共享文件中;将所述共享内存的写索引字段和所述消息的长度的和作为函数setWriteIndex()的输入,以更新所述共享内存的写索引字段。
在一种可能的实施例中,所述处理单元还用于:当所述守护进程读取所述消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
在一种可能的实施例中,所述处理单元具体用于,通过函数compact()对所述共享文件进行压缩;将所述共享内存的写索引字段和目标数组的长度的差作为函数setWriteIndex()的输入,以过滤所述读取的字节,所述目标数组用于所述守护进程读取所述消息。
本发明第三方面提供了一种电子设备,包括存储器、处理器,其特征在于,所述处理器用于执行存储器中存储的计算机管理类程序时实现如上述任意一项所述的方法的步骤。
本发明第四方面提供了一种计算机可读存储介质,其上存储有计算机管理类程序,其特征在于:所述计算机管理类程序被处理器执行时实现如上述任意一项所述的方法的步骤。
从以上技术方案可以看出,本发明实施例具有以下优点:在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。本申请实施例基于共享内存、文件锁、消息协议设计出一套适合单机施压机守护进程和施压子进程间的通信方案,以解决现有技术中父子进程通信内容不可靠的问题。
具体实施方式
本发明实施例提供了一种进程间通信的方法以及相关装置,用于解决现有技术中父子进程通信内容不可靠的问题。
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
本申请的说明书和权利要求书及上述附图中的术语“第一”、“第二”、“第三”、“第四”等(如果存在)是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。应该理解这样使用的数据在适当情况下可以互换,以便这里描述的实施例能够以除了在这里图示或描述的内容以外的顺序实施。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。
本申请实施例所涉及的性能测平台基于开源压测平台NGrinder,其中NGrinder压测结构是由控制台(console)管理施压机(agent),施压机集群创建具体的施压进程和线程对目标服务器进行压测,主要涉及console端和施压机agent之间的通信。
可以理解的是,java是跨平台的语言,由于java执行在JAVA虚拟机(java virtualmachine,JVM)上,导致java并不能利用操作系统提供的信号量、管道等通信方案,目前适合java进程间通信的方案通用方案是socket,但socket本质是解决互联网内跨机器跨进程间的网络通信,针对同一台施压机上不同进程间通信采用soket则不得不应对复杂的网络编程,和复杂多变的网络环境。因此基于NGrinder压测结构采用java输入输出流作为守护进程和施压进程间通信方案虽然简单,但是开发人员容易误用输入输出流,导致父子进程通信内容并不可靠。同时,基于java语言本身的限制,操作系统提供的单机进程间通信的其他如信号量、管道等并不使用java,目前业界java采用进程间通信的基本措施是采用socket,但socket编程过重。
有鉴于此,本申请实施例提供了一种进程间通信的方法,以基于进程间通信来解决单机不同进程间的网络通信,进程间通信将文件和进程内存做映射达到进程间共享的目的;进程间通过共享内存进行通信涉及到内存的可见性问题。另外,本申请实施例采用文件锁解决资源冲突问题;由于本申请实施例涉及的压测平台一台施压机上有一个守护进程和多个施压子进程,因此需要识别进程内容是守护进程和哪个施压子进程间的消息,本申请实施例设计一种私有进程间通信的消息协议,用于解决通道识别问题。即本申请实施例基于共享内存、文件锁、消息协议设计出一套适合单机施压机守护进程和施压子进程间的通信方案。具体请参阅图1a,为本发明实施例提供的一种进程间通信的方法的流程图,具体包括:
101、在施压机中创建共享文件;
102、获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存;
针对每台施压机,均创建一个共享文件,所述共享文件用于多个进程间信息的共享,其中,所述进程包括一个守护进程和多个施压子进程。在创建共享文件后,获得该共享文件对应的java文件管道,并利用该java文件管道建立一定的内存映射,可选的,本申请实施例中可建立所述共享文件与64k大小内存的映射空间,在实际应用中,内存的大小还可以为128k或者256k,具体此处不做限定。需要说明的是,一个守护进程和多个施压子进程共享一个该共享文件,且其中每个进程对应一个内存,各内存之间是相互隔离的,因此该共享文件对应多个内存,可以理解为基于共享文件的共享内存。例如,当某个进程的数据变化时,会同步到共享文件里,再同步到其他进程的内存中,为便于理解,假如施压机中有3个进程,包括1个守护进程(A进程)和2个施压子进程(B进程和C进程),采用基于共享文件的共享内存,由于各进程之间的内存都是互相隔离的,那B进程的数据如何让A进程获知呢。即B进程的数据更新后,同步到共享文件里,共享文件里的数据发生变化根据映射空间同步到A进程的内存里,这个过程需要的中介即为共享文件。实际应用中,具体函数实现如下:
其中,随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问,具体地,其随机访问文件的原理可以理解为把随机访问的文件对象看做存储在文件系统中的一个大型byte数组,然后通过指向该byte数组的光标或索引在该数组任意位置读取或写入任意数据。其中,swap.mm用于表示该共享文件。在获得共享文件后,通过系统函数randomAccessFile.getChannel()获得该共享文件对应的文件管道,其中,randomAccessFile是用来访问保存数据记录的文件,getChannel()是用于返回与文件输出流关联的唯一文件通道对象,即共享文件对应的文件管道,并将获得的共享文件对应的文件管道作为系统函数new MappedByteBufferWrap()的输入,以获得共享内存的缓存区,其中,该共享内存为可读内存。
103、对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;
需要说明的是,本申请实施例中,进程间通信涉及一个守护进程和多个施压子进程间的通信。其中,守护进程是消费者,施压机子进程是消息的生产者,两者之间是典型的生产者消费者模式,二者借助于共享文件内存做信息传递,是个异步的过程。当施压机子进程产生消息时,需要对该消息进行序列化,同时计算消息的长度,组成在共享文件中的完整消息。另外,为便于识别进程内容是守护进程和哪个施压子进程间的消息,本申请实施例提供一种消息协议,如图1b所示,为本申请实施例提供的一种可能的消息协议的示意图,包括,在共享文件首部开辟4个字节大小的写索引writeIndex,当没有消息写入共享文件内存时,writeIndex初始是0,另外针对每个消息包装消息长度和内容存入共享文件。需要说明的是,本申请实施例中没有定义读索引readIndex,因为消息在真正消费后会压缩共享文件同时维护writeIndex,所以本申请实施例中不需要readIndex。基于此,本申请实施例中对所述消息进行序列化处理,以在所述共享文件中组成完整的消息,可采用jdkSerializable()系统函数实现消息的序列化,其中,jdkSerializable()为序列化接口,即表明该类允许被序列化,再通过字符串输出函数put()函数在共享文件中组成完整的消息,具体实现函数如下:
其中,bodys用于表示序列化处理后的消息,bodys.length用于表示序列化处理后的消息的长度。另外,MappedByteBuffer是单个进程的buffer,buffer进行read操作和write操作后并不能改变其他进程的readIndex和writeIndex。
104、获取所述共享文件的文件锁;
可以理解的是,进程间通信需要保证资源的可见性,一个消息在没有完整写入文件时,施压机守护进程不能读取该文件,同时因为本实施例没有readIndex,导致消息的读取和写入都会更改writeIndex,鉴于此,本申请实施例通过获取共享文件的文件锁解决施压机守护进程和施压进程间的可见性,即避免所述一个守护进程和多个施压子进程之间的资源冲突。其中,将消息写入共享文件,通过系统函数tryLock()获取该共享文件的文件锁,其中,tryLock()函数表示尝试获取锁,若获取成功,标记下是该线程获取到了锁,然后返回true;若获取失败,此时直接返回false,告诉外层没有获取到锁。并在写入完成之后,通过系统函数lock.release()释放该文件锁,其中,lock.release()函数表示释放锁,若其返回值为1,则说明释放锁成功。具体实现函数如下:
105、将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段;
106、对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
本申请实施例中,包装MappedByteBuffer形成MappedByteBufferWrap类,对外提供put方法向共享文件写入消息;由于本申请实施例没有读索引readIndex,故读取消息的同时需要对共享文件进行压缩。即将消息写入共享内存,同时更新writeIndex索引字段,具体实现函数如下:
当消息写入共享文件中后,在守护进程读取该消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节,具体地,读取字节数组到目标数组中,并对空间进行压缩,过滤掉读取的字节,具体实现函数如下:
本申请实施例中,基于进程间通信来解决单机不同进程间的网络通信,进程间通信将文件和进程内存做映射达到进程间共享的目的;进程间通过共享内存进行通信涉及到内存的可见性问题。另外,本申请实施例采用文件锁解决资源冲突问题;由于本申请实施例涉及的压测平台一台施压机上有一个守护进程和多个施压子进程,因此需要识别进程内容是守护进程和哪个施压子进程间的消息,本申请实施例设计一种私有进程间通信的消息协议,用于解决通道识别问题。
上面从进程间通信的方法的角度对本发明实施例进行了描述,下面从通信装置的角度对本发明实施例进行描述。
请参阅图2,图2为本发明实施例提供的一种可能的通信装置的实施例示意图,具体包括:
创建单元201,用于在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;
获得单元202,用于获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;
处理单元203,用于当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;
写入单元204,用于将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。
在一种可能的实施例中,所述获得单元202具体用于,通过函数randomAccessFile.getChannel()获得所述共享文件对应的文件管道,所述randomAccessFile为用于支持读写随机存取文件的类;将所述文件管道作为函数MappedByteBufferWrap()的输入,以获得所述共享内存。
在一种可能的实施例中,所述处理单元203具体用于:通过函数jdkSerializable()实现所述消息的序列化;通过函数putInt()获得所述消息的长度,并根据put()函数在所述共享文件中组成完整的消息。
在一种可能的实施例中,所述获得单元202还用于:通过函数trylock()获取所述共享文件的文件锁,所述文件锁用于避免所述一个守护进程和多个施压子进程之间的资源冲突。
在一种可能的实施例中,所述写入单元204具体用于:通过函数mMappedByteBuffer.position()和mMappedByteBuffer.put()将所述消息写入所述共享文件中;将所述共享内存的写索引字段和所述消息的长度的和作为函数setWriteIndex()的输入,以更新所述共享内存的写索引字段。
在一种可能的实施例中,所述处理单元203还用于:当所述守护进程读取所述消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
在一种可能的实施例中,所述处理单元203具体用于,通过函数compact()对所述共享文件进行压缩;将所述共享内存的写索引字段和目标数组的长度的差作为函数setWriteIndex()的输入,以过滤所述读取的字节,所述目标数组用于所述守护进程读取所述消息。
请参阅图3,图3为本发明实施例提供的电子设备的实施例示意图。
如图3所示,本发明实施例提供了一种电子设备,包括存储器310、处理器320及存储在存储器320上并可在处理器320上运行的计算机程序311,处理器320执行计算机程序311时实现以下步骤:在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。
可选的,在一种可能的实施例中,所述处理器320具体用于:通过函数randomAccessFile.getChannel()获得所述共享文件对应的文件管道,所述randomAccessFile为用于支持读写随机存取文件的类;将所述文件管道作为函数MappedByteBufferWrap()的输入,以获得所述共享内存。
可选的,在一种可能的实施例中,所述处理器320具体用于:通过函数jdkSerializable()实现所述消息的序列化;通过函数putInt()获得所述消息的长度,并根据put()函数在所述共享文件中组成完整的消息。
可选的,在一种可能的实施例中,所述处理器320还用于:通过函数trylock()获取所述共享文件的文件锁,所述文件锁用于避免所述一个守护进程和多个施压子进程之间的资源冲突。
可选的,在一种可能的实施例中,所述处理器320具体用于:通过函数mMappedByteBuffer.position()和mMappedByteBuffer.put()将所述消息写入所述共享文件中;将所述共享内存的写索引字段和所述消息的长度的和作为函数setWriteIndex()的输入,以更新所述共享内存的写索引字段。
可选的,在一种可能的实施例中,所述处理器320还用于:当所述守护进程读取所述消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
可选的,在一种可能的实施例中,所述处理器320具体用于:所述对所述共享文件进行压缩并过滤掉所述守护进程读取的字节包括:通过函数compact()对所述共享文件进行压缩;将所述共享内存的写索引字段和目标数组的长度的差作为函数setWriteIndex()的输入,以过滤所述读取的字节,所述目标数组用于所述守护进程读取所述消息。
由于本实施例所介绍的电子设备为实施本发明实施例中一种通信装置所采用的设备,故而基于本发明实施例中所介绍的方法,本领域所属技术人员能够了解本实施例的电子设备的具体实施方式以及其各种变化形式,所以在此对于该电子设备如何实现本发明实施例中的方法不再详细介绍,只要本领域所属技术人员实施本发明实施例中的方法所采用的设备,都属于本发明所欲保护的范围。
请参阅图4,图4为本发明实施例提供的一种计算机可读存储介质的实施例示意图。
如图4所示,本实施例提供了一种计算机可读存储介质400,其上存储有计算机程序411,该计算机程序411被处理器执行时实现如下步骤:在施压机中创建共享文件,所述共享文件用于多个进程间信息的共享,所述多个进程包括一个守护进程和多个施压子进程;获得所述共享文件对应的文件管道,并根据所述文件管道获得共享内存,所述共享内存为与所述共享文件对应的可读内存;当所述施压子进程产生消息时,对所述消息进行序列化处理,以在所述共享文件中组成完整的消息;将所述消息写入所述共享文件中,并更新所述共享内存的写索引字段,以通过所述共享内存将所述消息从施压子进程发送给所述守护进程。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时还用于实现如下步骤:通过函数randomAccessFile.getChannel()获得所述共享文件对应的文件管道,所述randomAccessFile为用于支持读写随机存取文件的类;将所述文件管道作为函数MappedByteBufferWrap()的输入,以获得所述共享内存。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:通过函数jdkSerializable()实现所述消息的序列化;通过函数putInt()获得所述消息的长度,并根据put()函数在所述共享文件中组成完整的消息。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时还用于实现如下步骤:通过函数trylock()获取所述共享文件的文件锁,所述文件锁用于避免所述一个守护进程和多个施压子进程之间的资源冲突。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时具体用于实现如下步骤:通过函数mMappedByteBuffer.position()和mMappedByteBuffer.put()将所述消息写入所述共享文件中;将所述共享内存的写索引字段和所述消息的长度的和作为函数setWriteIndex()的输入,以更新所述共享内存的写索引字段。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时还用于实现如下步骤:当所述守护进程读取所述消息时,对所述共享文件进行压缩并过滤掉所述守护进程读取的字节。
可选的,在一种可能的实施例中,该计算机程序411被处理器执行时还用于实现如下步骤:所述对所述共享文件进行压缩并过滤掉所述守护进程读取的字节包括:通过函数compact()对所述共享文件进行压缩;将所述共享内存的写索引字段和目标数组的长度的差作为函数setWriteIndex()的输入,以过滤所述读取的字节,所述目标数组用于所述守护进程读取所述消息。
需要说明的是,在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详细描述的部分,可以参见其它实施例的相关描述。
本领域内的技术人员应明白,本发明的实施例可提供为方法、系统、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。
本发明是参照根据本发明实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式计算机或者其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本发明的优选实施例,但本领域内的技术人员一旦得知了基本创造概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本发明范围的所有变更和修改。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包括这些改动和变型在内。