linux共享内存实验原理,共享内存原理

Linux的2.2.x内核支持多种共享内存方式,如mmap()系统调用,Posix共享内存,以及系统V共享内存。

共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。

系统V共享内存原理

进程间需要共享的数据被放在一个叫做IPC共享内存区域的地方,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去。系统V共享内存通过shmget获得或创建一个IPC共享内存区域,并返回相应的标识符。内核在保证shmget获得或创建一个共享内存区,初始化该共享内存区相应的shmid_kernel结构注同时,还将在特殊文件系统shm中,创建并打开一个同名文件,并在内存中建立起该文件的相应dentry及inode结构,新打开的文件不属于任何一个进程(任何进程都可以访问该共享内存区)。所有这一切都是系统调用shmget完成的。

mmap原理

Linux 有一个系统调用叫 mmap(),这个 mmap() 可以把一个文件映射到进程的地址空间(进程使用的虚拟内存),这样进程就可以通过读写这个进程地址空间来读写这个文件。

你可能会觉得奇怪,我明明写的是内存啊,怎么会变成写文件了呢?他们之间是怎么转化的呢?

没错,你写的确实是内存,但是你写的这个内存不是普通的内存,你写在这个内存上的内容,过段时间后会被内核写到这个文件上面。而写文件,其实最后都会变成写数据到设备里(硬盘、Nand Flash 等)。

mmap的优点主要在为用户程序随机的访问,操作,文件提供了一个方便的操作方法;其次就是为不同进程共享大批量数据提供高效的手段;另外就是对特大文件(无法一次性读入内存)的处理提供了一种有效的方法。

共享内存原理

内核里存在着一个特殊的文件系统,这个文件系统的存储介质不是别的,正是 RAM。

在 shmget() 调用之后,系统会为你在这个文件系统上创建一个文件,但是这个时候仅仅是创建了这个文件。

然后你就应该调用 shmat() 了,调用 shmat() 之后,内核会使用 mmap 把这个文件映射到你的进程地址空间,这个时候你就能直接读写映射后的地址了。

过段时间,内核把你写的 内容写到了文件里面,但是,这个文件的存储介质是内存,所以他会怎么做?看明白了吧?

答案:他会写入内存呀

结论:使用内存映射文件来处理大文件可以提高效率。

使用文件映射与不使用文件映射

我们先来看看如果不使用内存映射文件的处理流程是怎样的,首先我们得先读出磁盘文件的内容到内存中,然后修改,最后回写到磁盘上。第一步读磁盘文件是要经过一次系统调用的,它首先将文件内容从磁盘拷贝到内核空间的一个缓冲区,然后再将这些数据拷贝到用户空间,实际上是两次数据拷贝。第三步回写也一样也要经过两次数据拷贝。

所以我们基本上会有四次数据的拷贝了,因为大文件数据量很大,几十GB甚至更大,所以拷贝的开销是非常大的。

而内存映射文件是操作系统的提供的一种机制,可以减少这种不必要的数据拷贝,从而提高效率。它由mmap()将文件直接映射到用户空间,mmap()并没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,所以只进行了一次数据拷贝 ,比read进行两次数据拷贝要好上一倍,因此,内存映射的效率要比read/write效率高。

一般来说,read write操作可以满足大多数文件操作的要求,但是对于某些特殊应用领域所需要的几十GB甚至更大的存储,这种通常的文件处理方法进行处理显然是行不通的。

mmap将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零。munmap执行相反的操作,删除特定地址区域的对象映射。

当使用mmap映射文件到进程后,就可以直接操作这段虚拟地址进行文件的读写等操作,不必再调用read,write等系统调用.但需注意,直接对该段内存写时不会写入超过当前文件大小的内容.

采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。

参考地址:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值