FileMapping写的内容什么时候会flush到磁盘?

FileMapping写的内容什么时候会flush到磁盘?

FileMapping写文件

这是个简单的file mapping 写文件例子:

void TestIOFileMapping() {
    HANDLE  hFile;

    hFile = CreateFile(L"testfilemapping.foo",
        GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        return;
    }

    HANDLE hMapping = CreateFileMapping(hFile,
        NULL,
        PAGE_READWRITE,
        0,
        MAX_FILESIZE,
        NULL);

    if (hMapping == NULL)
    {
        CloseHandle(hFile);
        return;
    }

    char* puchData = (char*)MapViewOfFile(hMapping,
        FILE_MAP_WRITE,
        0,
        0,
        0);

    if (puchData == NULL)
    {
        CloseHandle(hMapping);
        CloseHandle(hFile);
        return;
    }

    for (int i = 0; i < 10; i++)
    {
        memset(puchData + i * 1024, 0x41 + i, 1024);
    }

    UnmapViewOfFile(puchData);

//    FlushFileBuffers(hFile);
    CloseHandle(hMapping);
    CloseHandle(hFile);
}

什么时候写入磁盘?

因为上面的例子里面没有调用FlushFileBuffers(hFile);
所以,内存什么时候写入磁盘还真不好说。
一般有这几种可能:

  1. IRP_MJ_WRITE的对应函数(比如PreWrite),直接就被调用,然后进程号就是当前应用。
  2. PreWrite很快被调用,但是发现进程号是System进程的,也就是4号
  3. PreWrite过了好长一会才被调用,进程号是System进程的,也就是4号
  4. PreWrite一直都没有被调用 (实际上可能在关机前会写入,只是不容易察觉)

那么有哪些操作会强迫操作系统把缓存里面的数据写入磁盘呢?

强迫操作系统写入磁盘

其实应该有很多种,我知道的,比如:

  1. 读取文件的时候加上no buffering标志。
hFile = CreateFile(L"testfilemapping.foo",
        GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_FLAG_NO_BUFFERING,
        NULL);

当应用层这样去打开一个文件的时候,指定了FILE_FLAG_NO_BUFFERING,那么操作系统一看这个文件相关的还有部分内容在文件缓存里面,它就会先把内容写入磁盘,再返回CreateFile()。因为FILE_FLAG_NO_BUFFERING指的是从磁盘读取文件,操作系统需要保证数据一致性。
2. 通过CreateProcess之类的去创建一个进程(假如文件是个exe),那么操作系统也会在创建进程之前先把内容flush到磁盘
3. 。。。

猜你喜欢

转载自blog.csdn.net/zj510/article/details/85065171
今日推荐