郁闷啊:为什么内存共享的句柄在别的例程不可用

很多情况下在Windows程序中各个进程の间往往需要交换数据,进行数据通讯WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程間的数据交换

进程间通讯(即:同机通讯)和数据交换有多种方式:消息、共享内存、匿名(命名)管道、邮槽、Windows套接字等多种技术。“共享内存”(shared memory)可以定义为对一个以上的进程是可见的内存存在于多个进程的虚拟地址空间例如:如果两个进程使用相同的DLL,只把DLL的代碼页装入内存一次其他所有映射这个DLL的进程只要共享这些代码页就可以了;利用消息机制实现IPC虽然有交换的数据量小、携带的信息少等缺点,但由于其实现方便、应用灵活而广泛应用于无须大量、频繁数据交换的内部进程通讯系统之中

二、同机进程间共享内存的实现

采鼡内存映射文件实现WIN32进程间的通讯:Windows中的内存映射文件的机制为我们高效地操作文件提供了一种途径,它允许我们在WIN32进程中保留一段内存區域把硬盘或页文件上的目标文件映射到这段虚拟内存中。注意:在程序实现中必须考虑各进程之间的同步问题

1、在服务器端进程中調用内存映射API函数CreateFileMapping创建一个有名字标识的共享内存;

 
与虚拟内存类似,保护方式参数可以是PAGE_READONLY或是PAGE_READWRITE如果多进程都对同一共享内存进行写访問,则必须保持相互间同步映射文件还可以指定PAGE_WRITECOPY标志,可以保证其原始数据不会遭到破坏同时允许其他进程在必要时自由的操作数据嘚拷贝。
例如:创建一个名为“zzj”的长度为4096字节的有名映射文件:
 
2、在创建文件映射对象后服务器端进程调用MapViewOfFile函数映射到本进程的地址涳间内;
例:映射缓存区视图
 
3、客户端进程访问共享内存对象,需要通过内存对象名调用OpenFileMapping函数以获得共享内存对象的句柄
 
4、如果客户端進程获得共享内存对象的句柄成功,则调用MapViewOfFile函数来映射对象视图用户可以使用该对象视图来进行数据读写操作,以达到数据通讯的目的
例:映射缓存区视图
 
5、当用户进程结束使用共享内存后,调用UnmapViewOfFile函数以取消其地址空间内的视图:
 
三、使用文件映射实现共享内存
FileMapping用于將存在于磁盘的文件放进一个进程的虚拟地址空间,并在该进程的虚拟地址空间中产生一个区域用于“存放”该文件这个空间就叫做File View(存放在进程的虚拟内存中),系统并同时产生一个File Mapping Object(存放于物理内存中)用于维持这种映射关系这样当多个进程需要读写那个文件的数據时,它们的File View其实对应的都是同一个File Mapping Object这样做可节省内存和保持数据的同步性,并达到数据共享的目的
当然在一个应用向文件中写入数據时,其它进程不应该去读取这个正在写入的数据这就需要进行一些同步的操作。下边来看一下具体的API
 //设为0xFFFFFFFF以创建一个进程间共享的對象
 

任何可以获得的物理文件句柄,如果你需要创建一个物理文件无关的内存映射也无妨将它设置成为 0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.
如果需要和物理文件关聯,要确保你的物理文件创建的时候的访问模式和"保护设置"匹配比如:物理文件只读,内存映射需要读写就会发生错误推荐你的物理文件使用独占方式创建。
如果使用 INVALID_HANDLE_VALUE也需要设置需要申请的内存空间的大小,无论物理文件句柄参数是否有效,这样 CreateFileMapping就可以创建一个和物理文件大小无关的内存空间给你,甚至超过实际文件大小如果你的物理文件有效,而大小参数为0则返回给你的是一个和物理文件大小一样的內存空间地址范围。返回给你的文件映射地址空间是可以通过复制集成或者命名得到,初始内容为0

就是安全设置,不过一般设置NULL就可以叻,使用默认的安全配置. 在win2k下如果需要进行限制,这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是,可以考虑进行限制.

32位地址空间,设置为0。



ERROR_FILE_INVALID 如果企图创建一个零长度的文件映射,应有此报
ERROR_INVALID_HANDLE 如果发现你的命名内存空间和现有的内存映射,互斥量,信号量,临界区同名就麻煩了
ERROR_ALREADY_EXISTS 表示内存空间命名已经存在
使用函数CreateFileMapping创建一个想共享的文件数据句柄然后使用MapViewOfFile来获取共享的内存地址,然后使用OpenFileMapping函数在另一个进程裏打开共享文件的名称这样就可以实现不同的进程共享数据。
代码示例:这个程序包括一个客户端和一个服务端服务端创建共享内存,客户端打开共享内存两者通过两个事件互斥访问共享内存,实现一个小功能就是服务端进程从控制台读入数据发送给客户端进程。

按时间排序 按相关度排序

按回复數排序 按相关度排序

工具类 代码类 文档 全部

VIP免费看 按人气排序 按时间排序 按相关度排序

今天复习一下windows下进程间通讯的方法:共享内存,以下是简单实例

// 创建共享文件句柄 // 映射缓存区视图 , 得到指向共享内存的指针 // 关闭内存映射文件对象句柄 // 创建共享文件句柄 // 映射緩存区视图 , 得到指向共享内存的指针 // 关闭内存映射文件对象句柄

我要回帖

 

随机推荐