簡體   English   中英

共享內存或mmap - Linux C / C ++ IPC

[英]Shared Memory or mmap - Linux C/C++ IPC

上下文是進程間通信,其中一個進程(“服務器”)必須將固定大小的結構發送到在同一台機器上運行的許多偵聽進程(“客戶端”)。

在Socket Programming中我很自在。 為了使服務器和客戶端之間的通信更快並減少副本數量,我想嘗試使用共享內存(shm)或mmaps。

操作系統是RHEL 64位。

由於我是新手,請建議我應該使用哪個。 如果有人能指點我一本書或在線資源來學習同樣的東西,我會很感激。

謝謝你的回答。 我想補充一點,服務器(市場數據服務器)通常會接收多播數據,這將導致它每秒向“客戶端”“發送”大約200,000個結構,其中每個結構大約為100字節。 shm_open / mmap實現是否僅對大型數據塊或大量小型結構的性能優於套接字?

我將mmapshm_open一起用於將共享內存映射到進程的虛擬地址空間。 這是相對直接和干凈的:

  • 您使用某種符號名稱標識您的共享內存段,例如"/myRegion"
  • 使用shm_open您可以在該區域上打開文件描述符
  • 使用ftruncate可以將段擴大到所需的大小
  • 使用mmap將其映射到您的地址空間

shmat和Co接口(至少在歷史上)具有以下缺點:它們可能對您可以映射的最大內存量有限制。

然后,所有POSIX線程同步工具( pthread_mutex_tpthread_cond_tsem_tpthread_rwlock_t ,...)都具有初始化接口,允許您在進程共享上下文中使用它們。 所有現代Linux發行版都支持這一點。

這是否比套接字更可取? 性能方面它可能會有所不同,因為你不必復制東西。 但我想的主要觀點是,一旦你初始化了你的片段,這在概念上就更簡單了。 要訪問項目,您只需要鎖定共享鎖,讀取數據然后再次解鎖。

正如@R建議的那樣,如果你有多個讀者, pthread_rwlock_t可能是最好的鎖結構。

我曾經使用共享內存段實現了IPC庫; 這讓我可以避免復制(而不是將數據從發送方內存復制到內核空間,然后從內核空間復制到接收方內存,我可以直接從發送方復制到接收方內存)。

無論如何,結果並不像我預期的那樣好:實際上共享一個內存段是一個非常昂貴的過程,因為重新映射TLB條目和所有其余的都非常昂貴。 有關詳細信息,請參閱此郵件 (我不是那些人之一,但在開發我的庫時會收到這樣的郵件)。

結果僅適用於非常大的消息(例如超過幾兆字節),如果您使用的是小緩沖區,除非您願意編寫內核模塊,否則unix套接字是您可以找到的最優化的東西。

除了已經提出的建議之外,我還想提供另一種方法:IPv6節點/接口本地多播,即受限於環回接口的多播。 http://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xml#ipv6-multicast-addresses-1

起初這可能看起來很重,但大多數操作系統在零拷貝架構中實現環回套接字。 映射到傳遞給sendbuf參數的頁面將被分配一個額外的映射並在寫入時標記為copy,這樣如果發送程序覆蓋其中的數據,或者取消分配內容將被保留。

您應該使用強大的數據結構,而不是傳遞原始結構。 Netstrings http://cr.yp.to/proto/netstrings.txt和BSON http://bsonspec.org/浮現在腦海中。

在POSIX shm_open/mmap接口和舊的System V shmop之間進行選擇不會產生很大的不同,因為在初始化系統調用之后,您最終會遇到相同的情況:在各個進程之間共享的內存區域。 如果您的系統支持它,我建議使用shm_open/mmap ,因為這是一個設計更好的界面。

然后,您可以將共享內存區域用作通用黑板,其中所有進程都可以對其數據進行分頁。 困難的部分是同步訪問該區域的進程。 在這里,我建議避免編寫自己的同步方案,這可能非常困難且容易出錯。 相反,使用現有的基於工作套接字的實現來同步進程之間的訪問,並僅使用共享內存在進程之間傳輸大量數據。 即使使用這種方案,您也需要一個中央流程來協調緩沖區的分配,因此只有在您需要傳輸大量數據時,此方案才有價值。 或者,使用同步庫,如Boost.Interprocess

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM