[英]Fastest technique to pass messages between processes on Linux?
在Linux上,在C ++應用程序進程之間發送消息的最快技術是什么? 我隱約知道桌上有以下技巧:
還有更多的方法,最快的是什么?
盡管以上所有答案都非常好,但我認為我們必須討論什么是“最快” [並且它必須是“最快”還是僅僅是“足夠快”?
對於大消息,毫無疑問,共享內存是一種非常好的技術,並且在許多方面都非常有用。
但是,如果消息很小,則必須提出自己的消息傳遞協議和通知其他進程有消息的方法,這是不利的。
在這種情況下,管道和命名管道更容易使用-它們的行為非常類似於文件,您只需在發送方寫入數據,然后在接收方讀取數據。 如果發送方寫東西,則接收方會自動喚醒。 如果管道已滿,則發送方將被阻塞。 如果沒有更多來自發送方的數據,則接收方將自動被阻止。 這意味着可以用很少的幾行代碼來實現,並且很好地保證了它每次都可以正常工作。
另一方面,共享內存依賴於某種其他機制來通知另一線程“您有要處理的數據包”。 是的,如果要復制大量數據包,這將非常快-但是,如果管道之間確實存在巨大差異,我會感到驚訝。 主要好處是另一側不必從共享內存中復制數據-但它也依賴於有足夠的內存來容納所有“運行中”消息,或者發送者有能力阻止某些事情。
我並不是說“不要使用共享內存”,而是說沒有諸如“一種解決所有'最佳'問題的解決方案”之類的東西。
需要說明的是:首先,我將使用管道或命名管道(取決於適合的目的)來實現一個簡單的方法,並評估其性能。 如果實際花費大量時間來復制數據,那么我會考慮使用其他方法。
當然,另一個考慮應該是“我們是否要使用兩台單獨的計算機(或同一系統上的兩個虛擬機)來解決此問題。在這種情況下,網絡解決方案是一個更好的選擇-即使它不是最快的,我已經在我的機器上運行了本地TCP堆棧以進行基准測試,並獲得了20-30Gbit / s(2-3GB / s)的持續流量,而在同一進程中的原始內存大約為50-100GBit / s (5-10GB / s)(除非塊的大小非常小並且適合L1緩存)。我沒有測量標准管道,但是我希望它大約在這兩個數字的中間。對於許多不同的中型相當現代的PC來說都是正確的-顯然,在ARM,MIPS或其他嵌入式樣式的控制器上,期望所有這些方法的數量都更少。
我建議您也看一下: 如何在C中使用Linux共享內存 。
基本上,我在一台計算機上進行IPC時會丟棄諸如TCP和UDP之類的網絡協議。 這些具有打包開銷,並且綁定到甚至更多的資源(例如端口,環回接口)。
英國劍橋大學的NetOS系統研究小組已經完成了一些(開源)IPC基准測試。
源代碼位於https://github.com/avsm/ipc-bench 。
項目頁面: http : //www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ 。
結果: http : //www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html
這項研究已使用上述結果發表: http : //anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf
檢查CMA和kdbus: https ://lwn.net/Articles/466304/
我認為這些天最快的東西是基於AIO。 http://www.kegel.com/c10k.html
當您使用C ++標記此問題時,我建議使用Boost.Interprocess :
共享內存是最快的進程間通信機制。 操作系統將內存段映射到多個進程的地址空間中,以便多個進程可以在該內存段中進行讀寫操作,而無需調用操作系統功能。 但是,我們需要在讀取和寫入共享內存的進程之間進行某種同步。
我發現的一個警告是同步原語的可移植性限制 。 例如,OS X和Windows都不具有進程間條件變量的本地實現,因此它使用自旋鎖來模擬它們。
現在,如果使用支持POSIX進程共享原語的* nix,將不會有任何問題。
當涉及大量數據時,通過同步共享內存是一種好方法。
好吧,您可以使用linux共享內存 (也稱為SHM
在進程之間簡單地擁有一個共享內存段。
它很容易使用,請查看一些示例鏈接。
posix消息隊列非常快,但是有一些限制
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.