内存映射文件线程安全吗
我想知道是否可以使用 内存映射文件 对单个文件进行多线程写入,并确保两个线程不会写入同一区域(例如,通过交错固定大小的记录),从而减轻应用程序级别同步的需要,即在我的代码中不使用临界区或互斥锁。
然而,在谷歌搜索了一下之后,我仍然不确定。 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;
}
如果我要运行它,等待线程完成,取消映射文件并退出,我最终会得到一个包含连续整数的文件吗?
如果您能得到知情的答复,我将不胜感激。
I was wondering whether you could do multithreaded writes to a single file by using memory-mapped files, and making sure that two threads don't write to the same area (e.g. by interleaving fixed-size records), thus alleviating the need for synchronization at the application level, i.e. without using critical sections or mutexes in my code.
However, after googling for a bit, I'm still not sure. This link from Microsoft says:
First, there is an obvious savings of resources because both processes
share both the physical page of memory and the page of hard disk
storage used to back the memory-mapped file. Second, there is only one
set of data, so all views are always coherent with one another. This
means that changes made to a page in the memory-mapped file via one
process's view are automatically reflected in a common view of the
memory-mapped file in another process. Essentially, Windows NT is not
required to do any special bookkeeping to ensure the integrity of data
to both applications.
But does it apply to threads belonging to the same process? It would be plausible (since my writes are disjoint), but I don't know enough about the underlying implementation of memory mapping (e.g. what book-keeping the OS does) to be sure.
Example use case, where myFunction
is executed by each thread:
// 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;
}
If I were to run this, wait for the threads to finish, unmap the file and exit, would I end up with a file containing consecutive integers?
I would be grateful for an informed answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无论 MMF 视图是从多个进程还是一个进程内的多个线程访问,您都需要添加同步。 Fwiw,在一个进程内使用 MMF 进行内存共享没有任何意义。线程已经共享地址空间。
You'll need to add the synchronization regardless if the MMF view is accessed from multiple processes or multiple threads inside one process. Fwiw, it doesn't make any sense to use an MMF for memory sharing inside one process. Threads already share the address space.
是的。如果一个线程更改映射中的部分数据,则所有其他线程会立即看到该更改。
您需要确保线程协调它们的更改,以便没有线程访问不一致的视图(例如,所有访问都是通过关键部分)。
Yes. If one thread changes part of the data in the mapping, then all other threads immediately see that change.
You need to ensure the threads coordinate their changes so no thread is accessing an inconsistent view (eg. all access is via a critical section).