HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile, ...);
PVOID pvFile = MapViewOfFile(hFileMapping, ...);
// Use the memory-mapped file.
UnmapViewOfFile(pvFile);
CloseHandle(hFileMapping);
CloseHandle(hFile);
The preceding code shows the "expected" method for manipulating memory-mapped files. However, what it does not show is that the system increments the usage counts of the file object and the file-mapping object when you call MapViewOfFile. This side effect is significant because it means that we could rewrite the preceding code fragment as follows:
HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile, ...);
CloseHandle(hFile);
PVOID pvFile = MapViewOfFile(hFileMapping, ...);
CloseHandle(hFileMapping);
// Use the memory-mapped file.
UnmapViewOfFile(pvFile);
第一段代码应该是标准写法了,第二段代码有什么问题吗?标红的那句实在看不懂是啥意思。

解决方案 »

  1.   

    上面那段话简单的说就是说调用MapViewOfFile会增加文件对象和文件映射对象的引用计数。
      

  2.   

    如果不关心内核对象的统计信息就直接关掉其句柄
    不只是这个位置
    《windows核心编程》很多地方都有提醒读者CloseHandle并没有关闭对象
    只是影响引用计数
      

  3.   

    个人猜测由于调用 UnmapViewOfFile 会导致系统 increments the usage counts of the file object and the file-mapping object所以,这段代码涉及到的三个句柄,先关闭哪一个都可以。
    (嗯……,至少第二段代码所示的调用顺序是没问题的)
      

  4.   

    先看这个代码HANDLE hFile = CreateFileW(L"D:\\Downloads\\fg.ini",GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
        HANDLE hFileMapping = CreateFileMappingW(hFile,0,PAGE_READONLY,0,0,0);
        PVOID pvFile = MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);printf("%x,%x,%x,%p\n",GetCurrentProcessId(),hFile,hFileMapping,pvFile);
    getchar();
    CloseHandle(hFileMapping);
    CloseHandle(hFile);
    puts("closed");
    getchar();
    getchar();
    UnmapViewOfFile(pvFile);执行closehandle之前的对象状况
    lkd> .process 8997a5d0  
    Implicit process is now 8997a5d0
    lkd> !handle 30PROCESS 8997a5d0  SessionId: 0  Cid: 05a4    Peb: 7ffdd000  ParentCid: 055c
        DirBase: 0a3c0280  ObjectTable: e187cd40  HandleCount:  13.
        Image: cbtest.exeHandle table at e1f85000 with 13 entries in use0030: Object: 89937540  GrantedAccess: 00120089 Entry: e1f85060
    Object: 89937540  Type: (89a16040) File
        ObjectHeader: 89937528 (old version)
            HandleCount: 1  PointerCount: 1
            Directory Object: 00000000  Name: \Downloads\fg.ini {HarddiskVolume2}
    lkd> !object 89937540
    Object: 89937540  Type: (89a16040) File
        ObjectHeader: 89937528 (old version)
        HandleCount: 1  PointerCount: 1
        Directory Object: 00000000  Name: \Downloads\fg.ini {HarddiskVolume2}
    lkd> !handle 34PROCESS 8997a5d0  SessionId: 0  Cid: 05a4    Peb: 7ffdd000  ParentCid: 055c
        DirBase: 0a3c0280  ObjectTable: e187cd40  HandleCount:  13.
        Image: cbtest.exeHandle table at e1f85000 with 13 entries in use0034: Object: e196e240  GrantedAccess: 000f0005 Entry: e1f85068
    Object: e196e240  Type: (89a25040) Section
        ObjectHeader: e196e228 (old version)
            HandleCount: 1  PointerCount: 1
    lkd> !object e196e240
    Object: e196e240  Type: (89a25040) Section
        ObjectHeader: e196e228 (old version)
        HandleCount: 1  PointerCount: 1
    执行close之后的对象状况
    lkd> !object 89937540
    Object: 89937540  Type: (bad0b0b0) 
        ObjectHeader: 89937528 (old version)
        HandleCount: 0  PointerCount: 0
    lkd> !object e196e240
    Object: e196e240  Type: (bad0b0b0) 
        ObjectHeader: e196e228 (old version)
        HandleCount: 0  PointerCount: 0
    说明view并不需要文件对象和section对象的存在
    由于其他程序的影响,文件对象和节对象可能存在,但不能保证
    它们的关系见windows internals 5如果仅仅是同一个进程用这些,当然没问题,但如果涉及到进程间通信,则必须予以考虑
    下面的代码的OpenFileMapping不会成功,第二个CreateFileMapping得到的和第一个内容独立,如果这样的代码用于IPC则会与预料的不同HANDLE sec=CreateFileMappingW((HANDLE)-1,0,PAGE_READWRITE,0,64,L"sec");
        printf("%x\n",sec);
        PVOID view = MapViewOfFile(sec,FILE_MAP_READ,0,0,0);
        printf("%p\n",view);
        CloseHandle(sec);
        HANDLE sec2=OpenFileMappingW(FILE_MAP_WRITE,0,L"sec");
        HANDLE sec3=CreateFileMappingW((HANDLE)-1,0,PAGE_READWRITE,0,64,L"sec");
        printf("%x",sec2);
      

  5.   

    copy on write 和 5楼的讲述有没有什么关联?
    (都看不懂啊……)
      

  6.   


    pointerCount 和 HandleCount 哪一个才是引用计数呢?不是说MapViewOfFile会增加引用计数吗?那么为什么这两个值都为1呢?
      

  7.   

    引用不一定是句柄,所以pointerCount>=HandleCount 
    只有pointercount=0才可能释放掉对象
      

  8.   

    system increments the usage counts of the file object and the file-mapping object when you call MapViewOfFile
    这句话可以忘掉
      

  9.   

    这一下说不完,具体的看wrk或windows internals