首页
社区
课程
招聘
[求助]共享内存通信句柄释放问题
发表于: 2015-3-11 00:04 9037

[求助]共享内存通信句柄释放问题

2015-3-11 00:04
9037
A,B两个进程通信,使用共享内存方式,A为读者,B为写者,我想知道如下两个函数
在两个进程中需要各调用一遍吗?
CloseHandle(m_hSystemObject);
 UnmapViewOfFile(m_lpVoidSM);

我做的试验是只能在A中CloseHandle,否则A读取不到信息,UnmapViewOfFile这在AB调用没问题。

我的理解是

CloseHandle(m_hSystemObject);这里不能close,在EXE中close,因为是内核对象,在系统中是共用的一个映射,InfoShare4这个名字,虽然在两个进程中打开,但是返回值是一个即使名字不同,在这里关闭后再在exe里关闭,就关闭了两次,会产生错误。

m_hSystemObject = CreateFileMapping( (HANDLE)0xFFFFFFFF, &sa, PAGE_READWRITE, 0, m_dwSMLen, TEXT("InfoShare4") );

m_lpVoidSM = MapViewOfFile( m_hSystemObject, FILE_MAP_ALL_ACCESS, 0, 0, 0 );

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 209
活跃值: (143)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写创建-》写入-》写关闭-》读打开-》失败

写创建-》写入-》读打开-》写关闭-》读取-》读关闭-》成功

写创建-》写入-》读打开-》读取-》写关闭-》读关闭-》成功

写创建-》写入-》读打开-》读取-》读关闭-》写关闭-》成功
2015-3-11 09:05
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
3
我是不是应该创建两个同步对象呢?A发命令让B去写,B写完后A去读,A读完后关闭句柄,B也关闭句柄

这样一个同步写的对象,一个同步读的对象,是这样吗?
2015-3-11 11:11
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
明显楼主的概念理解有误区
“句柄”对应“对象”
“对象”有“引用计数”
“引用计数”是几,就说明被打开了几次
关闭句柄,即减少“对象”的“引用计数”,“引用计数”为0时删除“对象”
我所说的“对象”均指内核中的对象
2015-3-11 13:31
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
5
接着说,不同的句柄可能对应同一个对象
对不同句柄的操作实质上可能是对同一个对象的操作
以楼主的例子来看,共享内存来通信
即两个进程操作同一个对象(File Mapping)

正常的步骤是
一个进程CreateFileMapping
另一个进程OpenFileMapping

余下的操作就是
MapViewOfFile
//读写数据
UnmapViewOfFile
CloseHandle

就楼主的问题而言
是的,只要open或者create,必须调用CloseHandle
函数是成对调用的,即
open/create和CloseHandle是一对
MapViewOfFile和UnmapViewOfFile是一对

下面的调用顺序是错误的(或者说不规范的):
CreateFileMapping
MapViewOfFile
CloseHandle
UnmapViewOfFile

正确的顺序是:
CreateFileMapping
MapViewOfFile
UnmapViewOfFile
CloseHandle
2015-3-11 13:35
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
还要看你具体的使用情形
比如说进程A申请了一块共享内存,写入了数据,然后就不关心了
B进程启动后找这个共享内存,读取数据
如果是这种情形的话,A进程不能CloseHandle
因为在B没有打开这个对象的情况下,如果A调用了CloseHandle,则这一块共享内存会被彻底删除(引用计数=0)
---
这个问题应该是属于句柄和对象的关系问题
好了说了那么多希望楼主能明白
求采纳....
2015-3-11 13:46
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
7
这位哥解释的很明白,你一定是某个大神的小号,我忽略了引用计数这个东西了,还有个疑问
如果我在一个A和B进程都打开同一个对象,我在B中不关闭,在A中调用两次CloseHandle
这样可以吗?
2015-3-11 16:21
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
8
不可以,一个句柄一旦被关闭,“句柄”和“对象”就脱离了关系(内核中句柄表不存在映射关系了)
所以一个句柄只能被关闭一次
---
居然没采纳我的回复,白码了那么多字...
2015-3-11 16:38
1
雪    币: 23
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
。。。可以。
2015-3-11 17:00
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
10
不是啊哥,你跟上面那位哥的名字太像了shilyx,我才看出来你俩不是一个人,采纳你了,你的回答我看了好几遍,明白不少东西。
2015-3-11 17:31
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
11
啊啊我明白了。一个句柄只能对应一个对象,一个对象可以被多个句柄对应。谁创建的就由谁来关闭。
2015-3-11 17:33
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
12
哥你这么尿性,学了多久啊,看了什么书,有什么好书推荐吗,我在看核心编程。
2015-3-11 17:37
0
雪    币: 2161
活跃值: (750)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
13
最后一句话说的很模糊
“打开句柄”不完全是“创建对象”
“关闭句柄”不完全是“对象消亡”
当一个对象没有被任何东西引用,即引用计数为0,windows才会去回收这个对象所占用的资源
---
另外,我是自学的
这些对象啊句柄啊什么的深入理解还是要深入内核
不过纯应用层开发的话是用不到的
自己多动手
good luck
2015-3-11 18:33
0
雪    币: 60
活跃值: (444)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
14
我喜欢底层,Thanks
2015-3-11 18:48
0
雪    币: 121
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
我擦.r3的进程句柄引用计数和进程相关的.这样就明白了吧!
2015-3-13 11:27
0
游客
登录 | 注册 方可回帖
返回
//