内存映射文件线程安全吗

Vla*_*lad 5 memory windows multithreading thread-safety shared-memory

我想知道您是否可以通过使用内存映射文件对单个文件进行多线程写入,并确保两个线程不会写入同一区域(例如,通过插入固定大小的记录),从而减轻了同步需求在应用程序级别,即在我的代码中不使用关键部分或互斥体。

但是,在谷歌搜索了一段时间之后,我仍然不确定。Microsoft的此链接说:

首先,由于两个进程共享内存的物理页面和用于备份内存映射文件的硬盘存储页面,因此明显节省了资源。其次,只有一组数据,因此所有视图始终是一致的。这意味着,通过一个进程的视图对内存映射文件中的页面所做的更改会自动反映在另一进程的内存映射文件的公共视图中。从本质上讲,Windows NT不需要进行任何特殊的记账来确保两个应用程序的数据完整性。

但这是否适用于属于同一进程的线程?这是合理的(因为我的写作是不相交的),但是我对内存映射的底层实现(例如,操作系统做的记账)了解得还不够。

用例示例,其中myFunction由每个线程执行:

// crt     - index of current thread, in 0..n-1
// n       - thread count
// memArea - pointer to memory location obtained from mapping a file

void myFunction(int crt, int n, int*memArea){
    for (int i=1; i<512; i++)
        memArea[ ( sizeof(int)*( n*i + crt ) ] = n*i+crt;
}
Run Code Online (Sandbox Code Playgroud)

如果要运行此命令,请等待线程完成,取消映射文件并退出,我是否最终会得到包含连续整数的文件?

我将不胜感激。

Ric*_*ard 2

但它适用于属于同一进程的线程吗?

是的。如果一个线程更改映射中的部分数据,则所有其他线程会立即看到该更改。

您需要确保线程协调它们的更改,以便没有线程访问不一致的视图(例如,所有访问都是通过关键部分)。