導航:首頁 > 編程語言 > pythonmmap效率

pythonmmap效率

發布時間:2024-03-28 13:48:50

linux共享內存和mmap的區別

共享內存的創建
根據理論:
1. 共享內存允許兩個或多個進程共享一給定的存儲區,因為數據不需要來回復制,所以是最快的一種進程間通信機制。共享內存可以通過mmap()映射普通文件(特殊情況下還可以採用匿名映射)機制實現,也可以通過系統V共享內存機制實現。應用介面和原理很簡單,內部機制復雜。為了實現更安全通信,往往還與信號燈等同步機制共同使用。

mmap的機制如:就是在磁碟上建立一個文件,每個進程存儲器裡面,單獨開辟一個空間來進行映射。如果多進程的話,那麼不會對實際的物理存儲器(主存)消耗太大。

shm的機制:每個進程的共享內存都直接映射到實際物理存儲器裡面。

結論:

1、mmap保存到實際硬碟,實際存儲並沒有反映到主存上。優點:儲存量可以很大(多於主存)(這里一個問題,需要高手解答,會不會太多拷貝到主存裡面???);缺點:進程間讀取和寫入速度要比主存的要慢。

2、shm保存到物理存儲器(主存),實際的儲存量直接反映到主存上。優點,進程間訪問速度(讀寫)比磁碟要快;缺點,儲存量不能非常大(多於主存)

使用上看:如果分配的存儲量不大,那麼使用shm;如果存儲量大,那麼使用shm。

參看網路:http://ke..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 中的一段,並傳回一個指針。

重寫總結:
1、mmap實際就是操作「文件」。
2、映射文件,除了主存的考慮外。shm的內存共享,效率應該比mmap效率要高(mmap通過io和文件操作,或「需要寫完後用msync()同步一下」);當然mmap映射操作文件,比直接操作文件要快些;由於多了一步msync應該可以說比shm要慢了吧???
3、另一方面,mmap的優點是,操作比shm簡單(沒有調用比shm函數復雜),我想這也是許多人喜歡用的原因,包括nginx。

缺點,還得通過實際程序測試,確定!!!

修正理解(這也真是的,這個網站沒辦法附加;只能重寫了):
今天又細心研究了一下,發現網路這么一段說明:
2、系統調用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://ke..com/view/394293.htm
內存映射文件與虛擬內存有些類似,通過內存映射文件可以保留一個地址空間的區域,同時將物理存儲器提交給此區域,只是內存文件映射的物理存儲器來自一個已經存在於磁碟上的文件,而非系統的頁文件,而且在對該文件進行操作之前必須首先對文件進行映射,就如同將整個文件從磁碟載入到內存。由此可以看出,使用內存映射文件處理存儲於磁碟上的文件時,將不必再對文件執行I/O操作,這意味著在對文件進行處理時將不必再為文件申請並分配緩存,所有的文件緩存操作均由系統直接管理,由於取消了將文件數據載入到內存、數據從內存到文件的回寫以及釋放內存塊等步驟,使得內存映射文件在處理大數據量的文件時能起到相當重要的作用。另外,實際工程中的系統往往需要在多個進程之間共享數據,如果數據量小,處理方法是靈活多變的,如果共享數據容量巨大,那麼就需要藉助於內存映射文件來進行。實際上,內存映射文件正是解決本地多個進程間數據共享的最有效方法。

這里再總結一次:
1、mmap有兩種方式,一種是映射內存,它把普通文件映射為實際物理內存頁,訪問它就和訪問物理內存一樣(這也就和shm的功能一樣了)(同時不用刷新到文件)
2、mmap可以映射文件,不確定會不會像windows「內存映射文件」一樣的功能,如果是,那麼他就能映射好幾G甚至好幾百G的內存數據,對大數據處理將提供強大功能了???
3、shm只做內存映射,和mmap第一個功能一樣!只不過不是普通文件而已,但都是物理內存。

⑵ 如何用python一門語言通吃高性能並發,GPU計算和深度學習

第一個就是並發本身所帶來的開銷即新開處理線程、關閉處理線程、多個處理線程時間片輪轉所帶來的開銷。

實際上對於一些邏輯不那麼復雜的場景來說這些開銷甚至比真正的處理邏輯部分代碼的開銷更大。所以我們決定採用基於協程的並發方式,即服務進程只有一個(單cpu)所有的請求數據都由這個服務進程內部來維護,同時服務進程自行調度不同請求的處理順序,這樣避免了傳統多線程並發方式新建、銷毀以及系統調度處理線程的開銷。基於這樣的考慮我們選擇了基於Tornado框架實現api服務的開發。Tornado的實現非常簡潔明了,使用python的生成器作為協程,利用IOLoop實現了調度隊列。

第二個問題是資料庫的性能,這里說的資料庫包括MongoDB和Redis,我這里分開講。

先講MongoDB的問題,MongoDB主要存儲不同的用戶對於驗證的不同設置,比如該顯示什麼樣的圖片。
一開始每次驗證請求都會查詢MongoDB,當時我們的MongoDB是純內存的,同時三台機器組成一個復制集,這樣的組合大概能穩定承載八九千的qps,後來隨著我們驗證量越來越大,這個承載能力逐漸就成為了我們的瓶頸。
為了徹底搞定這個問題,我們提出了最極端的解決方案,乾脆直接把資料庫中的數據完全緩存到服務進程里定期批量更新,這樣查詢的開銷將大大降低。但是因為我們用的是Python,由於GIL的存在,在8核伺服器上會fork出來8個服務進程,進程之間不像線程那麼方便,所以我們基於mmap自己寫了一套夥伴演算法構建了一個跨進程共享緩存。自從這套緩存上線之後,Mongodb的負載幾乎變成了零。
說完了MongoDB再說Redis的問題,Redis代碼簡潔、數據結構豐富、性能強大,唯一的問題是作為一個單進程程序,終究性能是有上限的。
雖然今年Redis發布了官方的集群版本,但是經過我們的測試,認為這套分布式方案的故障恢復時間不夠優秀並且運維成本較高。在Redis官方集群方案面世之前,開源世界有不少proxy方案,比如Twtter的TwemProxy和豌豆莢的Codis。這兩種方案測試完之後給我們的感覺TwemProxy運維還是比較麻煩,Codis使用起來讓人非常心曠神怡,無論是修改配置還是擴容都可以在配置頁面上完成,並且性能也還算不錯,但無奈當時Codis還有比較嚴重的BUG只能放棄之。
幾乎嘗試過各種方案之後,我們還是下決心自己實現一套分布式方案,目的是高度貼合我們的需求並且運維成本要低、擴容要方便、故障切換要快最重要的是數據冗餘一定要做好。
基於上面的考慮,我們確定基於客戶端的分布式方案,通過zookeeper來同步狀態保證高可用。具體來說,我們修改Redis源碼,使其向zookeeper注冊,客戶端由zookeeper上獲取Redis伺服器集群信息並根據統一的一致性哈希演算法來計算數據應該存儲在哪台Redis上,並在哈希環的下一台Redis上寫入一份冗餘數據,當讀取原始數據失敗時可以立即嘗試讀取冗餘數據而不會造成服務中斷。

閱讀全文

與pythonmmap效率相關的資料

熱點內容
蛇跟一個小男孩的電影 瀏覽:777
0855 在線 瀏覽:968
電影院和圖書館相鄰用英語怎麼說 瀏覽:262
韓國 三個小時以上 愛情片 瀏覽:158
日本韓國懸疑推理片 瀏覽:462
華為雲通用計算型伺服器主頻 瀏覽:492
韓國愛情片網址 瀏覽:145
宣讀軍官晉升命令 瀏覽:856
朱藝彬的所有電影 瀏覽:683
李麗珍與徐錦江的電影 瀏覽:254
程序員介紹自己的能力 瀏覽:249
extjs源碼下載 瀏覽:794
古典文學txt 瀏覽:699
三級美電影 瀏覽:621
天浩列印伺服器怎麼修改ip地址 瀏覽:469
二龍湖浩哥系列觀看順序 瀏覽:158
哪個播放器英語影視劇多 瀏覽:964
和小矮人有關的電影 瀏覽:501
歐洲啪啪最多的電影 瀏覽:11
加密兔可以玩嗎 瀏覽:332