进程之间有时需要通信。系统提供的进程之间的通信机制在底层实现上都是利用内存映射文件技术。一个进程所能访问的所有低2GB地址都是自己的地址空间,当访问内核地址空间时就会受到内核的限制。这样一个进程当然无法访问其它进程了。为解决进程间通信的问题,内存映射文件技术被利用作为解决方案。原来内存映射文件只映射类似磁盘一类的存储器上的文件。而为了更快速地在进程之间通信,内存映射文件还可以提交物理内存。实现方法是通过访问同一个内存映射文件对象(映射到物理内存),两个进程或多个进程就能够访问到同一块物理内存,这样一个进程写到物理内存的数据,其它进程就能够看到了。而Windows CE虽然每个进程只占有32MB的地址空间,而且所有进程全部处于4GB的地址空间中,但是彼此还是不能够随意访问的。在Windows CE下除了使用内存映射文件技术外,还有一种方法也很适合使用,就是利用对象存储。对象存储本身使用RAM文件系统,用普通的操作文件的API就可以创建、读取存在于对象存储区域内的文件。
/Windows 目录就存在于对象存储区域内。我们可以利用在/Windows目录下创建文件来实现进程间通信。这种方法既实现简单,只需调用几个文件API函数,又可以减少通信时间,因为/Windows目录存在于物理内存中,数据I/O当然很快了。利用对象存储来实现进程之间的通信是我自己想出来的,MSDN或其它文档并没有这方面的说明。需要注意的就是对象存储区域的大小。另外从实现的代码量上看也不如内存映射文件技术。
下面讲解如何利用内存映射文件实现进程之间的通信。假设进程A和进程B需要通信,那么进程A需要先创建一个内存映射文件(之前不必调用CreateFileForMapping函数来创建文件,因为不需要创建文件)。这个内存映射文件可以是在永久存储器中,也可以是在内存中。为了减小通信时间,最好提交物理内存。进程A在调用CreateFileMapping函数时,参数1指定为INVALID_HANDLE_VALUE,这表示这个内存映射文件对象将要把物理内存提交到地址空间中。最后一个参数一定要指定一个名字。进程B也同样调用CreateFileMapping函数,而且参数相同。内核会根据名字来判断是否已经存在一个内存映射文件对象,如果创建了就返回原来的对象的句柄。接下去就不用细说了。参照5.1去执行就可以了。要注意的是进程B调用CreateFileMapping函数后要按如下代码检验函数执行结果:
HANDLE hMap;
hMap = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
1000,
L"abc");
if (hMap == NULL || GetLastError() != ERROR_ALREADY_EXISTS)
{
MessageBox(L"create file mapping fail");
return;
}
/Windows 目录就存在于对象存储区域内。我们可以利用在/Windows目录下创建文件来实现进程间通信。这种方法既实现简单,只需调用几个文件API函数,又可以减少通信时间,因为/Windows目录存在于物理内存中,数据I/O当然很快了。利用对象存储来实现进程之间的通信是我自己想出来的,MSDN或其它文档并没有这方面的说明。需要注意的就是对象存储区域的大小。另外从实现的代码量上看也不如内存映射文件技术。
下面讲解如何利用内存映射文件实现进程之间的通信。假设进程A和进程B需要通信,那么进程A需要先创建一个内存映射文件(之前不必调用CreateFileForMapping函数来创建文件,因为不需要创建文件)。这个内存映射文件可以是在永久存储器中,也可以是在内存中。为了减小通信时间,最好提交物理内存。进程A在调用CreateFileMapping函数时,参数1指定为INVALID_HANDLE_VALUE,这表示这个内存映射文件对象将要把物理内存提交到地址空间中。最后一个参数一定要指定一个名字。进程B也同样调用CreateFileMapping函数,而且参数相同。内核会根据名字来判断是否已经存在一个内存映射文件对象,如果创建了就返回原来的对象的句柄。接下去就不用细说了。参照5.1去执行就可以了。要注意的是进程B调用CreateFileMapping函数后要按如下代码检验函数执行结果:
HANDLE hMap;
hMap = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
1000,
L"abc");
if (hMap == NULL || GetLastError() != ERROR_ALREADY_EXISTS)
{
MessageBox(L"create file mapping fail");
return;
}