使用内存映象实现进程间全局变量

原创 2003年08月20日 21:41:00

使用内存映象实现进程间全局变量

编程时在同一程序中使用全局变量给我们带来了很多方便,大多数程序几乎都离不开全局变量。那么不同的程序之间呢?我们怎样在不同的程序(进程)之间共享数据呢?事实上,你可能已经注意到在不同的进程间使用全局变量在有些场合还是很有必要,这是一项相当有用的技术,基于某中特殊情况我们的确需要在我们开发的不同的程序间共享数据。比如有些软件你会发现安装后不止一个可执行文件,而且在运行时任务栏也不止出现一个进程,但在使用中你发现不同的进程竟向一个单独运行程序一样,效果很好。接下来我们仔细研究一下该技术:

要在不同进程间共享全局变量,应该首先想到我们可以通过不同的进程在内存中的同一块存储区域读取数据,那里就象一个公共场合一样,我们把这样的区域叫做内存映象文件。通过windows api我们可以很容易的在内存中创建这么一个区域并轻易的读取它。这里需要用到两个关键的api函数:CreateFileMappingMapViewOfFile,前者在内存中创建一个内存映象区,它需要一些参数包括这块区域的读写权限,唯一区域名称以及数据大小(这些参数将在下面代码的注释中给予说明,更多的参数说明请参看win sdk的帮助文件或查看msdn);后者返回一个指向这块区域的指针以便在程序中调用。下面我们将通过一个简单的例子来说明,这个例子由两个工程组成,一个通过一个按纽负责向内存映象区写入一个长度为11个字符的字符串(‘how are you‘,通过一个edit读入,如果edit中的字符数大于了11个程序将可能出错),另一个则通过一个按纽读出这个字符串,写入一个edit中。下面是部分的代码(为了节省篇幅,加上程序很简单,有些不会影想你阅读的代码没有贴出):

我们首先在第一个工程(窗口取名为SetValue)的单元的接口部分声明一个指向即将创建的内存区域的句柄和一个用来向这个区域写数据的指针变量:

var<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

  ……

  hFileMapping:HWND;//指向内存区域的句柄

  SetString:pchar;//这里应该使用标准的windows字符串而非delphi特有的string类型

这样我们可以在按纽的单击事件中编写相应的代码:

procedure TForm1.Button1Click(Sender: TObject);

begin

 hFileMapping:=CreateFileMapping($FFFFFFFF,nil,Page_ReadWrite,0,11,'MapString');

 //$FFFFFFFF表示使用虚拟文件,注意两个工程中应该使用同一个唯一的名称MapString

 if hFileMapping=0 then

  raise Exception.Create('Error creating map file!');

 SetString:=MapViewOfFile(hFileMapping,File_Map_Write,0,0,11);

 strcopy(SetString,pchar(Edit1.Text));

 //注意这里应该使用拷贝函数而不是直接赋值 SetString:=pchar(Edit1.Text)

end;

当然,我们还可以在这个主工程中编写一个释放内存映象的过程:

procedure TForm1.Button2Click(Sender: TObject);

begin

 UnMapViewOfFile(SetString);

 if hFileMapping<>0 then

  closehandle(hFileMapping);

end;

接下来是第2个工程的按纽单击事件,它和第一个工程几乎没有什么不同,只是我们修改了内存映象的读取权限为只读而以:

var

  ……

  GetString:pchar;

  hMapFileMaping:HWND;

procedure TForm1.Button1Click(Sender: TObject);

begin

 hMapFileMaping:=CreateFileMapping($FFFFFFFF,nil,Page_ReadOnly,0,11,'MapString');

//再次注意一定要使用唯一的名称(MapString)和第一个工程保持一致

 if hMapFileMaping=0 then

  raise Exception.Create('Error');

 GetString:=MapViewOfFile(hMapFileMaping,File_Map_Read,0,0,11);

 Edit1.Text:=String(GetString);

end;

现在我们便可以测试了,通过下图你可以看到测试情况:

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />CSDN_Dev_Image_2003-8-191723230.jpg

CSDN_Dev_Image_2003-8-191723232.jpg

当然,上面的程序只是一个例子,没有任何使用意义,只是为了介绍这种技术,起到抛砖引玉的作用,再实际编程中你可以更严格的控制共享变量。你还可以使用这种技术实现一些奇特的效果。关于一些api函数,它们大多都非常复杂,自己也还没有完全掌握。建议大家在编程中多查看delphi中的win sdk帮助,里面相当详细,一定能帮助大家学到更多的东西。

SendMessage进程间简单通信问题

 本例以两个VC Dialog application 为例用SendMessage进行两进程间简单通信:主要API:FindWindow(LPCTSTR lpClassName,    LPCTST...
  • zzq_gates
  • zzq_gates
  • 2007年04月19日 17:29
  • 592

C#下的进程间的通讯 -- 共享内存--内存互斥控制

  C#下的进程间的通讯 -- 共享内存篇 收藏  【摘要】这篇文章早就想发了,可是一直没有时间整理,今天总算发上来了。上次发了利用发消息实现的C#进程间的通讯,这次又使用共享内存了,他们应用范围是不...
  • rise51
  • rise51
  • 2011年01月11日 17:36
  • 547

Posex信号量 实现进程间的同步(生产者&消费者)

Posex信号量sem实现多个线程的互斥,只需在进程空间定义好sem_t变量即可,因为各个线程是共享该sem_t变量。同理,如果sem要实现进程间的互斥,这个sem_t的变量就要在共享存储中定义,因为...
  • ordeder
  • ordeder
  • 2014年03月10日 22:35
  • 1723

【共享内存】利用MFC写的进程间通信——内存共享

MFC写的程序,自己对共享内存的一点理解,赶紧记下来方便今后对照、修改。...
  • yzt33
  • yzt33
  • 2015年03月18日 15:31
  • 1232

PHP中进程间共享变量 shmop

类似于 asp中的 application 实现多用户的缓存共享进程间共享变量 用户在一个Web应用程序中导航时,如果能在Web服务器上存储用户或会话的特定数据,从而每次请求网页时能很容易地访问这些数...
  • leonzhang2008
  • leonzhang2008
  • 2010年03月22日 16:45
  • 5897

网络编程(40)—— 使用信号量semaphore进行多进程间的同步

本文主要介绍下在多进程中使用信号量semaphore的方法。在上一文中,我们已经知道semaphore和mutex对临界区访问控制的一个最主要区别就是semaphore可以跨进程使用,而mutex只能...
  • lzhui1987
  • lzhui1987
  • 2016年12月18日 14:20
  • 1695

[转]进程间通过共享内存方式传输大数据

转自:blog.chinaunix.net/uid-20682890-id-3567309.html 通过共享内存和信号量的乒乓机制实现大数据块在不同程序之间的数据传输。 zips:htt...
  • hailmy
  • hailmy
  • 2016年09月22日 09:37
  • 1007

进程间共享变量

在php中可以实现在进程间共享信息的途径,并保证能快速地访问这些共享数据。有两种方式:shmop 和 System V这两种共享内存扩展方式。   shmop使用的例子: // create k...
  • u010437896
  • u010437896
  • 2013年05月02日 17:38
  • 1379

《unix高级环境编程》进程间通信——共享内存

共享内存是允许两个或多个进程共享同一块内存区域
  • chenhanzhun
  • chenhanzhun
  • 2014年11月18日 16:13
  • 1362

Python 进程之间共享数据(全局变量)

进程之间共享数据(数值型): import multiprocessing def func(num): num.value=10.78 #子进程改变数值的值,主进程跟着改变 i...
  • houyanhua1
  • houyanhua1
  • 2017年10月15日 21:25
  • 1154
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用内存映象实现进程间全局变量
举报原因:
原因补充:

(最多只允许输入30个字)