在VB中用文件映射来进行进程通讯
2008-02-23 06:58:06来源:互联网 阅读 ()
在多个应用程序之间交换数据,我们自然会想到磁盘文件,但这种方法在实时系统中是不宜采用的,因为读写磁盘文件的时间效率往往不能满足实时要求。幸运的是,Windows提供了几种高效的进程间交换数据的机制,如管道,邮路和文件映射。以下我们只针对文件映射进行讨论。
一. 文件映射概念
所谓文件映射,简单地说,就是将磁盘文件(或部分)映射到某段内存空间,对磁盘文件的访问转变成对内存的访问,显然,这大大提高了访问速度。
实际的映射过程是通过几个API函数来实现的,首先需要创建一个“文件映射对象”,而这个对象是共享的,各个进程可将对象映射到自己的内存地址空间,各进程的映射地址不一定相同,但地址中的内容却一定是相同的,各进程对各自的映射地址的访问都归结为对“文件映射对象”的访问。
如上所言,我们可以认为“文件映射”是将文件映射到内存供各进程共享。那我们何不直接开辟一块全局内存来共享呢?这在32位Windows中是行不通的,因为全局内存在32位Windows中不是多进程共享的对象。因此,文件映射在进程间通信中扮演了重要的角色。
二. 示例
我们姑且把这个示例叫做“数据采集系统”,它由两个工程组成:Sampling.vbp(采样)和Manage.vbp(管理)。
Sampling.vbp包含两个文件:Form1.frm,Module1.bas。清单如下:
Form1.frm:
VERSION 5.00
Begin VB.Form Form1
Caption = "Sampling"
ClientHeight = 1440
ClientLeft = 48
ClientTop = 288
ClientWidth = 4416
LinkTopic = "Form1"
ScaleHeight = 1440
ScaleWidth = 4416
StartUpPosition = 3 '窗口缺省
Begin VB.CommandButton cmdStop
Caption = "Stop"
Enabled = 0 'False
Height = 372
Left = 2160
TabIndex = 2
Top = 360
Width = 972
End
Begin VB.CommandButton cmdStart
Caption = "Start"
Height = 372
Left = 840
TabIndex = 1
Top = 360
Width = 972
End
Begin VB.TextBox Text1
Height = 372
Left = 120
TabIndex = 0
Text = "Text1"
Top = 840
Width = 4092
End
Begin VB.Timer Timer1
Enabled = 0 'False
Interval = 60
Left = 0
Top = 0
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Private Sub cmdStart_Click()
Pub_Timer1Run = False
Pub_LastTime = Timer()
Timer1.Enabled = True
cmdStart.Enabled = False
cmdStop.Enabled = True
End Sub
Private Sub cmdStop_Click()
Timer1.Enabled = False
cmdStart.Enabled = True
cmdStop.Enabled = False
End Sub
Private Sub Form_Load()
Call CreateMap
End Sub
Private Sub Form_Unload(Cancel As Integer)
Call CloseMap
End Sub
Private Sub Timer1_Timer()
Static tm As Single, Dlt As Single
Static i As Integer
Static dtNow As Date
Static S As String
Static v(1 To Pub_LoopN) As Single
If Pub_Timer1Run Then Exit Sub
Pub_Timer1Run = True
tm = Timer(): dtNow = Now()
Dlt = tm - Pub_LastTime
If Sgn(Dlt) = -1 Then '两次时间跨午夜0点
Dlt = Dlt 86400! '86400 = 24 * 3600
End If
Do While Dlt >= Pub_Period
Pub_LastTime = tm
Call GetV(v())
Call GetFromMap(strBuffer)
If Left(strBuffer, 1) = "*" Then
S = " " & Format(dtNow, Pub_FormatDT)
For i = 1 To Pub_LoopN
S = S & " " & Format(v(i), Pub_FormatV)
Next i
strBuffer = S: Call CopyToMap(strBuffer)
Text1.Text = S
Else
'Add to File
End If 'Left(strBuffer, 1) = "*"
Exit Do
Loop
Pub_Timer1Run = False
End Sub 'Timer1_Timer
Private Sub GetV(v() As Single)
Const MaxV = 4000!
Dim i As Integer
Randomize
For i = 1 To Pub_LoopN
v(i) = CSng(MaxV * Rnd)
Next i
End Sub 'GetV
Module1.bas:
Attribute VB_Name = "Module1"
Option Explicit
#Const Sampling = True '编译常数Sampling=Ture:采样, =False:管理
Public DiskFileName As String '实时样本磁盘文件名
Public MapFileName As String '前者的(内存)映射文件名
Public FileHandle As Long '磁盘文件句柄
Public MapHandle As Long '映射文件句柄
Public MapAddress As Long '映射地址
Public strBuffer As String '实时样本缓冲
Public LenBuffer As Long '缓冲区长度
Public Const Pub_LoopN = 2 '通道数目
Public Const Pub_FormatDT = "yyyy-mm-dd hh:mm:ss" '日期/时间格式
Public Const Pub_FormatV = "0000.000" '样本数据格式
Public Pub_LenDT As Long '日期/时间宽度
Public Pub_LenV As Long '样本数据宽度
Public Const Pub_Period = 2! '采样周期(秒)
Public Pub_LastTime As Single '上次采样时间
Public Pub_Timer1Run As Boolean '中断例程在运行标志
Public Const FILE_MAP_WRITE = &H2
Public Const FILE_MAP_READ = &H4
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:播放flc文件动画
下一篇:用VB设计聚焦框程序
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash