关于Windows中内存映射文件有1疑问
关于Windows中内存映射文件有一疑问
最近写一个程序需要实现多个进程共享一个计数器(也就是一个整数变量Count,每当进程做完某件事后就会将变量加1)。
变量Count在一个内存映射文件(采用CreateFileMapping和MapViewOfFile实现)。
接下来就处理进程间同步,否则会出现计数丢失的问题。我采用命名互斥体Mutex来实现。计数器累加大致步骤如下:
1.锁定互斥体: WaitForSingleObject
2.修改计数变量: Count++
3.释放互斥体: ReleaseMutex
代码本身没啥问题,但是我有些觉得太麻烦,而且速度不快。于是采用了InterlockedIncrement函数,累加步骤如下:
InterlockedIncrement(&Count)
就一句代码,于是速度超快,经过同时4个进程共40亿次测试没有出现计数丢失。
但是还有点担心,因为不知道“内存映射文件”到底是怎么实现的。
先来说说InterlockedIncrement函数。
InterlockedIncrement的核心代码就一句:
lock xadd dword ptr [ecx], eax
lock指令的解释是:“封锁总线,封锁数据指令LOCK(Lock Bus Instruction)”
也就是说指令执行时数据总线是锁定的,无论有多少进程、线程、CPU在跑,都只有这条指令在访问内存,很好的实现了变量独占累加,这是硬件架构保证的。(我怀疑Windows中的那些同步对象内部也是靠Lock指令)
我担心的是“内存映射文件”到底是什么?它真的是系统将物理内存映射到进程空间吗?
你想它的名字中带有“文件”二字,我一直以为它是个磁盘文件。
虽然我测试的结果是InterlockedIncrement函数可以实现自己的要求,但是这会不会是暂时现象内,
比如说当系统内存不足时、换了一个系统时(我用的是Win2003)会不会就不行了?
觉得想弄清这些问题就得知道“内存映射文件”是如何实现的,判断会不会当系统升级时它的实现方法就不一样了。
但是不知道哪里有这方面的资料,不是那种讲解怎么使用内存映射文件的资料。
------解决方案--------------------
Windows核心编程一书
------解决方案--------------------
1 内存映射可以仅仅是内存,与文件无关;当然也可以关联到文件
2 多个进程用同一个内存映射 配合InterlockedIncrement 是不会丢失计数的
3 如果内存真的不足了 自然无法创建内存映射
4 如果4个进程是同一个进程的话 可以直接采用共享节配合InterlockedIncrement 比内存映射要好
5 如果4个进程不是同一个进程的话 可以设计一个进入到所有四个进程中的dll 将共享节放入dll中 也可以达到和4相同的效果 但是略麻烦;如果本身就已经有了这个dll了,那么也很方便的
最近写一个程序需要实现多个进程共享一个计数器(也就是一个整数变量Count,每当进程做完某件事后就会将变量加1)。
变量Count在一个内存映射文件(采用CreateFileMapping和MapViewOfFile实现)。
接下来就处理进程间同步,否则会出现计数丢失的问题。我采用命名互斥体Mutex来实现。计数器累加大致步骤如下:
1.锁定互斥体: WaitForSingleObject
2.修改计数变量: Count++
3.释放互斥体: ReleaseMutex
代码本身没啥问题,但是我有些觉得太麻烦,而且速度不快。于是采用了InterlockedIncrement函数,累加步骤如下:
InterlockedIncrement(&Count)
就一句代码,于是速度超快,经过同时4个进程共40亿次测试没有出现计数丢失。
但是还有点担心,因为不知道“内存映射文件”到底是怎么实现的。
先来说说InterlockedIncrement函数。
InterlockedIncrement的核心代码就一句:
lock xadd dword ptr [ecx], eax
lock指令的解释是:“封锁总线,封锁数据指令LOCK(Lock Bus Instruction)”
也就是说指令执行时数据总线是锁定的,无论有多少进程、线程、CPU在跑,都只有这条指令在访问内存,很好的实现了变量独占累加,这是硬件架构保证的。(我怀疑Windows中的那些同步对象内部也是靠Lock指令)
我担心的是“内存映射文件”到底是什么?它真的是系统将物理内存映射到进程空间吗?
你想它的名字中带有“文件”二字,我一直以为它是个磁盘文件。
虽然我测试的结果是InterlockedIncrement函数可以实现自己的要求,但是这会不会是暂时现象内,
比如说当系统内存不足时、换了一个系统时(我用的是Win2003)会不会就不行了?
觉得想弄清这些问题就得知道“内存映射文件”是如何实现的,判断会不会当系统升级时它的实现方法就不一样了。
但是不知道哪里有这方面的资料,不是那种讲解怎么使用内存映射文件的资料。
------解决方案--------------------
Windows核心编程一书
------解决方案--------------------
1 内存映射可以仅仅是内存,与文件无关;当然也可以关联到文件
2 多个进程用同一个内存映射 配合InterlockedIncrement 是不会丢失计数的
3 如果内存真的不足了 自然无法创建内存映射
4 如果4个进程是同一个进程的话 可以直接采用共享节配合InterlockedIncrement 比内存映射要好
5 如果4个进程不是同一个进程的话 可以设计一个进入到所有四个进程中的dll 将共享节放入dll中 也可以达到和4相同的效果 但是略麻烦;如果本身就已经有了这个dll了,那么也很方便的