Linux2.2.x内核支持多种共享内存方法,例如mmap()系统调用、Posix共享内存和SystemV共享内存。
共享内存可以说是最有用的进程间通信方法,也是最快的IPC形式。两个不同的进程A和B共享内存,这意味着相同的物理内存被分配给进程A和B各自的进程地址空间。进程A可以立即看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一内存区域,因此需要某种同步机制,例如互斥锁和信号量。
SystemV共享内存原理
进程间需要共享的数据放在一个叫做IPC共享内存区域的地方。所有需要访问共享区域的进程都必须将共享区域分配给本进程的地址空间。SystemV共享内存通过shmget检索或创建IPC共享内存区域并返回相应的标识符。内核确保shmget获取或创建共享内存区域,并初始化共享内存区域对应的shmid_kernel结构。请注意,它将同时在特殊文件系统shm中创建并打开一个同名文件。并在内存中建立该文件对应的文件和inode结构,新打开的文件不属于任何进程(任何进程都可以访问共享内存区域)。这一切都是由shmget系统调用完成的。
Linux有一个系统调用,叫做mmap(),这个mmap()可以将一个文件映射到进程地址空间(进程使用的虚拟内存),以便进程可以读写。进程地址空间来读取和写入该文件。
你可能会觉得很奇怪,我明明是在写入内存,为什么还要写入文件呢?他们是如何转的?
是的,你写的其实是内存,但是你写的内存不是普通的内存。你写入这块内存的内容会在一段时间后被内核写入到这个文件中。写文件实际上最终是将数据写入设备(硬盘、NandFlash等)。
mmap的主要优点是为用户程序提供了一种方便的操作方法来对文件进行随机访问、操作,另外对于超大文件(无法一次读入内存)提供了一种方便的操作方法。有效的方法。
内核中有一个特殊的文件系统。这个文件系统的存储介质就是RAM。
在shmget()调用之后,系统会为您在该文件系统上创建一个文件,但这一次它只是创建该文件。
然后你调用shmat(),内核会使用mmap将文件映射到进程地址空间。此时就可以对分配的地址进行读写操作了。。
一段时间后,内核会将您输入的内容写入文件中。但是这个文件的存储介质是内存,那么它会做什么呢?你明白吗?
答:会写入内存
首先我们看一下如果不使用内存映射文件的情况下的处理流程。首先我们需要将磁盘文件的内容读入内存,然后修改,最后写回磁盘。读取磁盘文件的第一步是通过系统调用。它首先将文件内容从磁盘复制到内核空间的缓冲区,然后将数据复制到用户空间副本。第三步回写也需要两份数据。
所以我们基本上会有四份数据副本,因为大文件的数据量非常大,几十GB甚至更大,所以复制的成本非常高。
内存映射文件是操作系统提供的一种机制,可以减少不必要的数据拷贝,从而提高效率。它使用mmap()将文件直接映射到用户空间,在页错误处理期间不会复制数据。由于mmap()将文件直接映射到用户空间,因此函数根据这种映射关系将文件直接从硬盘复制到用户空间。因此,只进行一次数据拷贝,读取时效果是两次数据拷贝的两倍。因此,内存映射的效率高于读/写的效率。
一般来说,读操作可以满足大多数文件操作的要求,但对于一些需要数十GB甚至更大存储空间的特殊应用领域,则采用这种常见的文件处理方式。不工作。
mmap将文件或其他对象映射到内存。文件被分配到多个页面如果文件大小不是所有页面大小的总和,则最后一页上未使用的空间将被清空。munmap执行相反的操作,删除特定地址范围的对象映射。
使用mmap将文件映射到进程后,就可以直接使用这个虚拟地址来读写文件,而不必调用读写直接访问这个段的系统调用进行写入时内存,不会写入超过当前文件大小的内容。
参考地址:
上一篇:服务器内存与台式机内存的区别
下一篇:进程间通信共享内存