共享內存的建立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系統調用並非徹底爲了用於共享內存而設計的。它自己提供了不一樣於通常對普通文件的訪問方式,進程能夠像讀寫內存同樣對普通文件的操做。而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
這裏再總結一次:
一、mmap有兩種方式,一種是映射內存,它把普通文件映射爲實際物理內存頁,訪問它就和訪問物理內存同樣(這也就和shm的功能同樣了)(同時不用刷新到文件)
二、mmap能夠映射文件,不肯定會不會像windows「內存映射文件」同樣的功能,若是是,那麼他就能映射好幾G甚至好幾百G的內存數據,對大數據處理將提供強大功能了???
三、shm只作內存映射,和mmap第一個功能同樣!只不過不是普通文件而已,但都是物理內存。
但願你們出意見!!!
轉載地址:http://blog.chinaunix.net/uid-16979052-id-3494641.html