内存映射文件(二)

内存映射文件(一):http://my.oschina.net/simplefocus/blog/288141


  1. Windows允许我们以同一个数据文件为后备存储器来创建多个文件映射对象。Windows并不保证这些不同的文件映射对象的各个视图是一致的。系统只能保证在同一文件映射对象的多个视图间保持一致
  2. 可以调用MapViewOfFileViewEx来指定系统在指定地址预定地址空间:
    LPVOID MapViewOfFileEx(HANDLE hFileMappingObject,
                            DWORD dwDesiredAccess,
                            DWORD dwFileOffsetHigh,
                            DWORD dwFileOffsetLow,
                            SIZE_T dwNumberOfBytesToMap,
                            LPVOID lpBaseAddress);
    • 指定的目标地址必须是分配粒度的整数倍,否则函数将返回NULL
    • 如果系统无法将文件映射到指定的地址(通常是由于文件太大,因此导致与其他已预定的地址空间发生重叠),那么函数会失败并返回NULL。函数不会尝试去找另一个能够容纳文件的地址空间
    • 当把NULL传给lpBaseAddress时,MapViewOfFileEx等同于MapViewOfFile
    • 指定的地址必须在进程的用户模式分区中,否则将返回NULL
  3. 以页交换文件为后备存储器的内存映射文件:
    • 如果为了共享数据而必须让应用程序在磁盘上创建数据文件并把数据保存在文件中,那将非常不方便;考虑到这一点,可以创建以页交换文件为后备存储器的内存映射文件,这样就不需要用磁盘上专门的文件来作为后备存储器了
    • 由于不必创建或打开一个专门的磁盘文件,因此不需要调用CreateFile。只需要调用CreateFileMapping,并将INVALID_HANDLE_VALUE作为hFile参数传入。这告诉系统创建的文件映射对象的物理存储器不是磁盘上的文件,而是希望系统从页交换文件中调拨物理存储器
  4. 稀疏调拨的内存映射文件:假设进程要与另一个进程共享一整个电子表格
    int nCellData[1000][1000];
    既要满足多进程共享电子表格,且电子表格很多时候大部分的单元格并不会使用,这种情况下稀疏调拨内存映射文件时最好的选择:
    1. CreateFileMapping提供了一种方法,即在fdwProtect参数中指定SEC_RESERVE或SEC_COMMIT标志;只有当以页交换文件为后备存储器创建文件映射对象的时候,这些标志才有意义。SEC_COMMIT标志让CreateFileMapping从页交换文件中调拨存储器,这和不指定任何标志具有相同的结果
    2. 在调用CreateFileMapping的时候传入SEC_RESERVE标志,那么系统不会从页交换文件中调拨物理存储器,它只返回文件映射对象的句柄。之后我们可以调用MapViewOfFile或MapViewOfFileEx来给这个文件映射对象创建一个视图。MapViewOfFile和MapViewOfFileEx会预定一块地址空间区域,但不会给区域调拨任何物理存储器。视图访问区域中的内存地址将引发访问违例
    3. 为了给共享区域调拨物理存储器,我们只需调用VirtualAlloc。我们可以只调拨部分存储器给用MapViewOfView或MapViewOfViewEx预定的区域。当我们一旦给MapViewOfView和MapViewOfViewEx预定的区域调拨了存储器,所有映射了同一个文件映射对象的视图的其他进程都可以成功地访问已调拨的页面
    4. 如果内存映射文件时通过SEC_RESERVE标识预定得到的,便不能用VirtualFree来撤销调拨给它的存储器

你可能感兴趣的:(内存映射文件,内存共享,稀疏调拨内存映射文件)