2009-08-05 33 views
70

大家似乎認爲命名管道比套接字IPC更快。他們有多快?我更喜歡使用套接字,因爲它們可以進行雙向通信,而且非常靈活,但是如果數量相當大,它會選擇速度而不是靈活性。IPC的性能:命名管道VS套接字

+10

您的里程將有所不同。 :)描述您的預期應用的典型用途,並選擇兩者中較好的一個。然後配置匿名管道,其他領域和家庭的套接字,信號量和共享內存或消息隊列(SysV和POSIX),帶有數據字的實時信號或任何其他信息。 '管(2)'(呃,'mkfifo(3)'?)可能是勝利者,但直到你嘗試纔會知道。 – pilcrow 2009-08-06 01:31:40

+2

SysV消息隊列FTW!我不知道他們是否快速,我只是對他們有一個情有獨鍾。 – 2010-09-21 17:44:35

+2

這種情況下的「速度」是什麼?總體數據傳輸率?或延遲(第一個字節到達接收器的速度有多快)?如果你想快速的本地數據傳輸,那麼很難擊敗共享內存。如果延遲是一個問題,那麼問題會變得更有趣...... – 2016-03-30 20:28:52

回答

4

命名管道和套接字在功能上並不等同;套接字提供更多功能(它們是雙向的,用於開始)。

我們不能告訴你哪個表現會更好,但我強烈懷疑這並不重要。

Unix域套接字將完成tcp套接字的功能,但只能在本地計算機上執行,並且(可能有點)開銷較低。

如果Unix套接字速度不夠快並且傳輸大量數據,請考慮在客戶端和服務器之間使用共享內存(這是很複雜的設置)。

Unix和NT都有「命名管道」,但它們在功能集中完全不同。

+1

那麼,如果你打開2管道,那麼你也得到比迪的行爲。 – Pacerier 2017-02-19 21:13:24

46

我建議你採用最簡單的第一個,仔細分離IPC機制,這樣就可以從插座改爲管,但我肯定會帶插座先走了。 在搶先優化之前,您應該確定IPC性能是一個問題。

而且,如果您因爲IPC速度的麻煩,我想你應該考慮切換到共享內存而不是去管。

如果你想做一些傳輸速度測試,你應該嘗試socat,這是一個非常通用的程序,允許你創建幾乎任何類型的隧道。

+2

+1爲socat,在 – galaktor 2014-01-15 08:43:55

+1

@shodanex之前沒有看到過,「共享內存」是指你的意思是線程還是..? – Pacerier 2017-02-19 21:09:09

25

我會用shodanex同意,它看起來像你過早地想優化的東西是沒有問題的。除非你知道套接字將成爲瓶頸,我只是使用它們。

很多通過命名管道發誓的人找到了一點積蓄(取決於其他所有東西的寫入情況),但最終得到的代碼與IPC做的有用工作相比,花在IPC回覆上的時間更多。當然,非阻塞方案有助於這一點,但這些可能會非常棘手。花費數年時間,將舊代碼帶入現代,我可以說,在我見過的大多數情況下,加速幾乎爲零。

如果你真的認爲套接字會讓你放慢速度,那麼請使用共享內存走出門外,仔細注意你如何使用鎖。再一次,在所有的現實中,你可能會發現一個小的加速,但是注意到你正在浪費一部分等待互斥鎖。我不打算主張去futex hell(很好,不是相當於地獄在2015年,這取決於你的經驗)。

英鎊磅,插座(幾乎)總是最好的方式去用戶空間IPC下單片內核..和(通常)最容易調試和維護。

6

如果你不需要速度,套接字是最簡單的方法!

如果你正在尋找的是速度,最快的解決方案是共享內存,而不是命名管道。

7

對於雙向通信與命名管道:

  • 如果你有幾道工序,就可以打開兩個管道的兩個方向(processA2ProcessB和processB2ProcessA)
  • 如果你有很多過程,你可以打開並出於對每一個工藝管道(processAin,processAout,processBin,processBout,processCin,processCout等)
  • 或者你可以去混合一如既往:)

南ed管道很容易實現。

E.g.我使用命名管道在C中實現了一個項目,這要歸功於基於標準文件輸入輸出的通信(fopen,fprintf,fscanf ...),它非常簡單和清晰(如果這也是一個考慮因素)。

我甚至用java編碼他們(我被序列化,並在他們發送的對象!)

命名管道有一個缺點:

  • ,因爲他們依靠他們不擴大在多臺計算機就像插座文件系統(假設共享文件系統不是一個選項)
20

請記住,套接字不一定意味着IP(以及TCP或UDP)。您還可以使用Unix套接字(PF_UNIX),它提供了一個顯着的性能改進了連接到127.0.0.1

+1

Windows怎麼樣? – Pacerier 2017-02-19 21:10:11

+1

@Place不幸的是,你不能像在UNIX上的抽象名字空間一樣在Windows上創建本地套接字。我發現PF_​​UNIX套接字比本頁介紹的大多數其他方法快得多(> 10%)。 – EntangledLoops 2017-04-14 15:04:05

4

套接字的一個問題是它們沒有辦法刷新緩衝區。有一種叫做Nagle算法,收集所有數據並在40ms後刷新它。因此,如果它是響應性而不是帶寬,那麼使用管道可能會更好。

您可以使用套接字選項TCP_NODELAY禁用Nagle,但讀取結束將永遠不會在一次讀取調用中收到兩條短消息。所以測試一下,我沒有得到這個結果,並且在共享內存中使用pthread互斥體和信號量實現了基於內存映射的隊列,避免了很多內核系統調用(但是現在它們不再很慢)。

+1

「所以測試它」< - 生活的話。 – Koshinae 2016-04-18 09:03:25

1

您可以使用像ZeroMQ [zmq/0mq]這樣的輕量級解決方案。它使用起來非常簡單,而且插座的速度要快得多。

+1

您可能會喜歡,猜猜Amit,Martin SUSTRIK的下一個作品 - POSIX兼容**'nanomsg' **。無論如何,歡迎和享受這個偉大的地方,併成爲它的積極貢獻會員。 – user3666197 2017-04-02 06:06:59

+0

肯定會嘗試,謝謝。 – 2017-04-02 13:05:23