【问题标题】:Splitting shared memory?拆分共享内存?
【发布时间】:2012-07-17 21:37:46
【问题描述】:

使用CreateFileMapping() 分配一块共享内存并给出它的句柄。一些数据是使用MapViewOfFile() 写入的——称之为“源”

现在我希望将共享内存分成许多小块并获取它们的句柄。
有没有办法在不再次调用CreateFileMapping() 并从“源”复制的情况下做到这一点?

OpenFileMapping()MapViewOfFile() 具有适当的偏移量将起作用,但问题是,在这种情况下,调用 OpenFileMapping() 的进程可以访问由其他进程写入“源”中的数据,它们可能会被使用了错误的偏移量。

长话短说,我正在寻找类似OpenFileMapping(String name, UINT **offset**, ...)的东西


最后一句话有误导性。

我真正想做的是这样的:

<Host process>
HANDLE hShm = CreateFileMapping(INVALID_HANDLE_VALUE, ..., "shm");
void* pShm = MapViewOfFile(hShm);
UINT numShms = *(UINT*)pShm;   // first 4 bytes stores number of shared memory blocks
HANDLE *hShmSplit = new HANDLE[numShms];    
for(size_t i=0; i<numShms; i++) {
   TCHAR shmName[32];
   wsprintf(shmName, "shm%d", i);
   // suppose offset is set
   pShm+=offset;
   hShmSplit[i] = *CreateFileMappingFromExistingMapping*(pShm, shmName);
}
CloseHandle(hShm);   // no longer used

<Client process>
TCHAR* shmName="shm1";
HANDLE hShm = OpenFileMapping(shmName);
LPVOID p = MapViewOfFile(hShm);
// use shared memory 
// Now the client process has access to shm1 but not to shm2, shm3, or other shm_x's.

【问题讨论】:

  • ...你为什么不能把指针传递到它的中间?
  • 这是一个多进程项目,所以...
  • 那么您希望其他进程如何获取打开的文件?
  • 按名称:OpenFileMapping(..., LPCTSTR 名称)
  • 那么你需要的是某种传递有效偏移量的方法。

标签: c++ winapi


【解决方案1】:

共享内存通过将相同的物理内存页面映射到多个进程的虚拟地址空间来工作。一旦一个进程可以访问一个内存页面,它就可以访问整个页面。内存页的长度为 4KB(尽管有 Itanium)。

因此,如果您可以将映射文件拆分为多个片段,那么这些片段必须从页面边界开始,并且大小必须是 4KB 的精确倍数。所以它不会那么有用。

如果您想与不同的客户端进程安全地共享不同的内存位,则必须为每个进程使用单独的映射。

【讨论】:

    猜你喜欢
    • 2014-06-21
    • 2014-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 2013-06-11
    • 2010-10-31
    • 2012-11-04
    相关资源
    最近更新 更多