【VB开源代码栏目提醒】:网学会员为需要VB开源代码的朋友们搜集整理了在VB中用文件映射来进行进程通讯-计算机论文 - 其它论文相关资料,希望对各位网友有所帮助!
在
VB中用文件映射来进行进程通讯-
计算机论文 真诚为您服务 四川行政财贸治理干部学院计算机治理系卿静 当我们用
VB开发应用系统时可能涉及多进程问题。
比如工业上应用较多的数据采集系统也许就需要两个进程一个是“采样程序”另一个是“治理程序”“采样程序”做单一的采集样本
工作而“治理程序”则对样本进行分析存储输出各种图表等等。
为了便于维护“采样程序”与“治理程序”各自作为独立的应用程序而运行那么“治理程序”怎样才能取得“采样程序”所采集的数据呢这就是所谓进程间的通信
问题。
在多个应用
程序之间交换数据我们自然会想到磁盘文件但这种方法在实时
系统中是不宜采用的因为读写磁盘文件的时间效率往往不能满足实时要求。
幸运的是Windows提供了几种高效的进程间交换数据的机制如管道邮路和文件映射。
以下我们只针对文件映射进行讨论。
一.文件映射概念所谓文件映射简单地说就是将磁盘文件映射到某段内存空间对磁盘文件的访问转变成对内存的访问显然这大大提高了访问速度。
实际的映射过程是通过几个API函数来实现的首先需要创建一个“文件映射对象”而这个对象是共享的各个进程可将对象映射到自己的内存地址空间各进程的映射地址不一定相同但地址中的内容却一定是相同的各进程对各自的映射地址的访问都归结为对“文件映射对象”的访问。
如上所言我们可以认为“文件映射”是将文件映射到内存供各进程共享。
那我们何不直接开辟一块全局内存来共享呢这在32位Windows中是行不通的因为全局内存在32位Windows中不是多进程共享的对象。
因此文件映射在进程间
通信中扮演了重要的角色。
二.示例我们姑且把这个示例叫做“数据采集系统”它由两个工程组成Sampling.vbp和Manage.vbp。
Sampling.vbp包含两个文件Form1.frmModule1.bas。
清单如下Form1.frmVERSION5.00BeginVB.FormForm1Caption “Sampling“ClientHeight1440ClientLeft48ClientTop288ClientWidth4416LinkTopic“Form1“ScaleHeight1440ScaleWidth4416StartUpPosition3FalseHeight372Left2160TabIndex2Top360Width972EndBeginVB.CommandButtoncmdStartCaption“Start“Height372Left840TabIndex1Top360Width972EndBegin
VB.TextBoxText1Height372Left120TabIndex0Text“Tex t1“Top840Width4092EndBeginVB.TimerTimer1Enabled0/computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’ngleDltAsSingleStaticiAsIntegerStaticdtNowAsDateStaticSAsStringStaticvAsSingleIfPub_Timer1RunThenExitSubPub_Timer1RunTruetmTimerdtNowNowDlttm-Pub_LastTimeIfSgn-1Then86400243600EndIfDoWhileDltPub_PeriodPub_LastTimetmCallGetVCallGetFromMapIfLeft““ThenS““FormatFori1ToPub_LoopNSS““FormatPub_FormatVNextistrBufferSCallCopyToMapText1.TextSElseLeft““ExitDoLoopPub_Timer1RunFalseEndSub/computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’Fori1ToPub_LoopNvCSngNextiEndSub编译常数SamplingTure采样False治理PublicDiskFileNameAsString前者的映射文件名PublicFileHandleAsLong映射文件句柄PublicMapAddressAsLong实时样本缓冲PublicLenBufferAsLong通道数目PublicConstPub_FormatDT“yyyy-mm-ddhhmmss“样本数据格式PublicPub_LenDTAsLong样本数据宽度PublicConstPub_Period2上次采样时间PublicPub_Timer1RunAsBoolean /computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’_ByValhTemplateFileAsLongAsLongDeclareFunctionWriteFileLib“kernel32“_AsLongDeclareFunctionFlushFileBuffersLib“kernel32“AsLongEndIfIfSamplingThenDeclareFunctionCreateFileMappingLib“kernel32“Alias“CreateFileMappingA“_AsLongElseDeclareFunctionOpenFileMappingLib“kernel32“Alias“OpenFileMappingA“_AsLongEndIf DeclareFunctionMapViewOfFileLib“kernel32“_AsLongDeclareFunctionUnmapViewOfFileLib“kernel32“_AsLongInitVarPublicSubCopyToMapIfMapAddress0ThenCalllstrcpynEndIfEndSubPublicSubGetFromMapIfMapAddress0ThenCalllstrcpynBy ValSByValMapAddressLenBuffer1EndIfEndSubPublicSubCloseMapIfMapAddress0ThenCallUnmapViewOfFileMapAddress0EndIfIfMapHandle0ThenCallCloseHandleMapHandle0EndIfIfFileHandle0ThenCallCloseHandleFileHandle0EndIfEndSub/computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’MapAddressMapViewOfFileEndSubOpenMapEndIf/computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’288ClientWidth4416LinkTopic“Form1“ScaleHeight1440ScaleWidth4416StartUpPosition3FalseInterval60Left0Top0EndEndAttributeVB_Name“Form1“AttributeVB_GlobalNameSpaceFalseAttributeVB_CreatableFalseAttributeVB_Predeclar edIdTrueAttributeVB_ExposedFalseOptionExplicitPrivateSubcmdStart_ClickIfOpenMap0ThenMsgBox“采样程序未运行“vbOKOnly““ExitSubEndIfPub_Timer1RunFalseTimer1.EnabledTruecmdStart.EnabledFalseEndSubPrivateSubForm_UnloadCallCloseMapEndSubPrivateSubTimer1_TimerStatictmAsSingleDltAsSingleStaticiAsIntegerStaticdtNowAsDateStaticSAsStringStaticvAsSingleIfPub_Timer1RunThenExitSubPub_Timer1RunTrueCallGetFromMapIfLeft““ThenstrBuffer““MidCallCopyToMapText1.TextstrBufferEndIfPub_Timer1RunFalseEndSub/computer/PCYY/200703/82797.asp/computer/PCYY/200703/82797.aspid2/computer/PCYY/200703/82797.aspid3/computer/PCYY/200703/82797.aspid4/computer/PCYY/200703/82797.aspid5/computer/PCYY/200703/82797.aspid6/computer/PCYY/200703/82797.aspid7/computer/PCYY/200703/82797.aspid8/computer/PCYY/200703/82797.aspid9/computer/PCYY/200703/82797.aspid10/computer/PCYY/200703/82797.aspid11/computer/PCYY/200703/82797.aspid12/computer/PCYY/200703/82797.aspid13/computer/PCYY/200703/82797.aspid14’在Module1.bas中用到几个与文件映射有关的API函数分述如下1.CreateFileMapping创建文件映射对象参数hFileLong——欲在其中创建映射的一个已经打开的磁盘文件句柄LpFileMappingAttributesLong——通
常用0表示使用默认安全对象FlProtectLong——打开映射的方式DwMaximumSizeHighdwMaximumSizeLowLong——共同表示文件映射的最大长度通常均设为0表示磁盘文件的实际长度LpNameString——指定文件映射对象的名称。
返回值Long——新建文件映射对象的句柄。
2.OpenFileMapping打开一个现成的文件映射对象参数dwDesiredAccessLong——用API常数表示的对文件映射的访问方式bInheritHandleLong——返回值对与子进程的继续属性常设为FalselpNameString——预备打开的文件映射对象的名称。
返回值Long——指定的文件映射对象的句柄。
3.MapViewOfFile将一个文件映射对象映射到当前应用程序空间参数hFileMappingObjectLong——文件映射对象的句柄dwDesiredAccessLong——用API常数表示的对文件映射的访问方式dwFileOffsetHighdwFileOffsetLowLong——共同表示文件中的映射起点通常均设为0表示从文件的起始处开始映射dwNumberOfBytesToMapLong——要映射的字节数通常设为0表示映射整个文件映射对象。
返回值Long——文件映射在内存中的起始地址。
4.UnmapViewOfFile解除当前应用程序中的一个文件映射对象的映射地址空间参数lpBaseAddr ess要解除映射的文件映射起始地址。
返回值Long——非零表示成功零表示失败。
Sampling.vbp的启动窗体Form1.frm在装载时创建一个文件映射这个创建过程分三步首先通过CreateFileWriteFileFlushFileBuffers建立一个具有指定长度的磁盘文件DiskFileName然后由CreateFileMapping创建一个对应于磁盘文件DiskFileName的文件映射对象MapFileName最后用MapViewOfFile将文件映射对象映射到应用程序地址MapAddress。
在本例中磁盘文件建立后便不再与之打交道以后的操作均针对其映射地址空间。
采样通过触发定时器Timer1周期性的进行。
每次采样首先通过GetV取得原始样本并放入数组v然后将其存入映射地址空间以便“治理程序”取用。
样本在映射地址空间的存放形式为“x采样时间样本值1样本值2”。
其中x是一个标记当它为空格时表示新样本为“”时表示已取用。
为了方便程序处理设置了一个样本缓冲strBuffer由它与映射地址空间交换数据CopyToMap和GetFromMap也是用于这个目的CopyToMap是复制S到映射地址空间而GetFromMap是从映射地址空间取值送到S。
在“采样程序”运行过程中“治理程序”由于某种原因可能长时间不取用样本这时“采样程序”应当把样本存放到另外的磁盘文件以免丢失样本。
考虑到本文主题和文章篇幅本例未做处理。
Manage.vbp启动窗体Form1.frm很简单仅仅从
演示的角度将映射地址空间的数据取出并显示。
试验时先运行“采样”再运行“治理”观察两个窗体中的样本数据我们会发现他们几乎是同步的。
感谢文件映射