mmap和shm共享内存的区别和联系

共享内存的建立html

根据理论:linux

 1. 共享内存容许两个或多个进程共享一给定的存储区,由于数据不须要来回复制,因此是最快的一种进程间通讯机制。共享内存能够经过mmap()映射普通文件(特殊状况下还能够采用匿名映射)机制实现,也能够经过系统V共享内存机制实现。应用接口和原理很简单,内部机制复杂。为了实现更安全通讯,每每还与信号灯等同步机制共同使用。

mmap的机制如:就是在磁盘上创建一个文件,每一个进程存储器里面,单独开辟一个空间来进行映射。若是多进程的话,那么不会对实际的物理存储器(主存)消耗太大。


nginx

shm的机制:每一个进程的共享内存都直接映射到实际物理存储器里面。windows


结论:

一、mmap保存到实际硬盘,实际存储并无反映到主存上。优势:储存量能够很大(多于主存)(这里一个问题,须要高手解答,会不会太多拷贝到主存里面???);缺点:进程间读取和写入速度要比主存的要慢。

二、shm保存到物理存储器(主存),实际的储存量直接反映到主存上。优势,进程间访问速度(读写)比磁盘要快;缺点,储存量不能很是大(多于主存)

使用上看:若是分配的存储量不大,那么使用shm;若是存储量大,那么使用shm。



缓存

参看百度:http://baike.baidu.com/view/1499209.htm安全

mmap就是一个文件操做函数

 

看这些百度的描述:测试

mmap()系统调用使得进程之间经过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程能够向访问普通内存同样对文件进行访问,没必要再调用read(),write()等操做。 成功执行时,mmap()返回被映射区的指针,munmap()返回0。失败时,mmap()返回MAP_FAILED[其值为(void *)-1],munmap返回-1。errno被设为如下的某个值 EACCES:访问出错EAGAIN:文件已被锁定,或者太多的内存已被锁定EBADF:fd不是有效的文件描述词EINVAL:一个或者多个参数无效 ENFILE:已达到系统对打开文件的限制ENODEV:指定文件所在的文件系统不支持内存映射ENOMEM:内存不足,或者进程已超出最大内存映射数量 EPERM:权能不足,操做不容许ETXTBSY:已写的方式打开文件,同时指定MAP_DENYWRITE标志SIGSEGV:试着向只读区写入 SIGBUS:试着访问不属于进程的内存区参数fd为即将映射到进程空间的文件描述字,大数据

 

通常由open()返回,同时,fd能够指定为-1,此时须指定 flags参数中的MAP_ANON,代表进行的是匿名映射(不涉及具体的文件名,避免了文件的建立及打开,很显然只能用于具备亲缘关系的进程间通讯)网站

 

相关文章参考:

 

mmap函数是unix/linux下的系统调用,来看《Unix Netword programming》卷二12.2节有详细介绍。

mmap系统调用并非彻底为了用于共享内存而设计的。它自己提供了不一样于通常对普通文件的访问方式,进程能够像读写内存同样对普通文件的操做。而Posix或系统V的共享内存IPC则纯粹用于共享目的,固然mmap()实现共享内存也是其主要应用之一。
          mmap系统调用使得进程之间经过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程能够像访问普通内存同样对文件进行访问,没必要再 调用read(),write()等操做。mmap并不分配空间, 只是将文件映射到调用进程的地址空间里, 而后你就能够用memcpy等操做写文件, 而不用write()了.写完后用msync()同步一下, 你所写的内容就保存到文件里了. 不过这种方式没办法增长文件的长度, 由于要映射的长度在调用mmap()的时候就决定了.

简单说就是把一个文件的内容在内存里面作一个映像,内存比磁盘快些。
基本上它是把一个档案对应到你的virtual memory 中的一段,并传回一个指针。

 

 

 

 

重写总结:

一、mmap实际就是操做“文件”。

二、映射文件,除了主存的考虑外。shm的内存共享,效率应该比mmap效率要高(mmap经过io和文件操做,或“须要写完后用msync()同步一下”);固然mmap映射操做文件,比直接操做文件要快些;因为多了一步msync应该能够说比shm要慢了吧???

三、另外一方面,mmap的优势是,操做比shm简单(没有调用比shm函数复杂),我想这也是许多人喜欢用的缘由,包括nginx。

 

缺点,还得经过实际程序测试,肯定!!!

 

修正理解(这也真是的,这个网站没办法附加;只能重写了):

今天又细心研究了一下,发现百度这么一段说明:

二、系统调用mmap()用于共享内存的两种方式: 
(1)使用普通文件提供的内存映射:适用于任何进程之间;此时,须要打开或建立一个文件,而后再调用mmap();典型调用代码以下: 
fd=open(name, flag, mode); 
if(fd<0) 
... 
ptr=mmap(NULL, len , PROT_READ|PROT_WRITE, MAP_SHARED , fd , 0); 经过mmap()实现共享内存的通讯方式有许多特色和要注意的地方,咱们将在范例中进行具体说明。 
(2)使用特殊文件提供匿名内存映射:适用于具备亲缘关系的进程之间;因为父子进程特殊的亲缘关系,在父进程中先调用mmap(),而后调用fork()。那么在调用fork()以后,子进程继承父进程匿名映射后的地址空间,一样也继承mmap()返回的地址,这样,父子进程就能够经过映射区域进行通讯了。注意,这里不是通常的继承关系。通常来讲,子进程单独维护从父进程继承下来的一些变量。而mmap()返回的地址,却由父子进程共同维护。

看了一下windows“内存映射文件”:http://baike.baidu.com/view/394293.htm

内存映射文件与虚拟内存有些相似,经过内存映射文件能够保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,并且在对该文件进行操做以前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此能够看出,使用内存映射文件处理存储于磁盘上的文件时,将没必要再对文件执行I/O操做,这意味着在对文件进行处理时将没必要再为文件申请并分配缓存,全部的文件缓存操做均由系统直接管理,因为取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到至关重要的做用。另外,实际工程中的系统每每须要在多个进程之间共享数据,若是数据量小,处理方法是灵活多变的,若是共享数据容量巨大,那么就须要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

 

这里再总结一次:

一、mmap有两种方式,一种是映射内存,它把普通文件映射为实际物理内存页,访问它就和访问物理内存同样(这也就和shm的功能同样了)(同时不用刷新到文件)

二、mmap能够映射文件,不肯定会不会像windows“内存映射文件”同样的功能,若是是,那么他就能映射好几G甚至好几百G的内存数据,对大数据处理将提供强大功能了???

三、shm只作内存映射,和mmap第一个功能同样!只不过不是普通文件而已,但都是物理内存。

 

但愿你们出意见!!!

 转载地址:http://blog.chinaunix.net/uid-16979052-id-3494641.html

相关文章
相关标签/搜索