2012-04-30 179 views
1

有幾個套接字問題,並且找不到明確的是或否,所以如果它是轉發,請提前道歉:)平臺是Linux 2.6.30,C++應用程序。網絡還很新,即將加速。套接字問題

  1. 套接字API線程是否安全?例如,如果我在不使用互斥鎖的情況下從多個線程發送數據,還是必須使用自己的互斥鎖確保這一點?

  2. 輪詢/選擇以檢查我的發送是否會阻止然後發送,而不僅僅是發送並讓發送API內部排隊處理髮送是否更好?如果線程無論如何會阻塞(如果我不使用超時,那是),我真的不明白爲什麼需要發送後跟一個發送。

  3. 在Linux中,套接字是否默認爲零拷貝,或者是否存在涉及的副本?如果存在副本(不是以API的形式,而是以粒度的形式),是否有大小限制?如果答案是內核確實做了副本,是否有零拷貝套接字?

  4. 如果我必須在兩臺機器之間進行通信,我會假設多個套接字將比單個套接字使用更好的帶寬。這是一個正確的假設嗎?在兩臺普通的Linux機器之間使用全部BW的最佳方式是什麼?

5.你最喜歡的測量接口上當前帶寬使用情況的工具是什麼?這可能只是一個偏好,我看着iptraf等,但希望看到別人使用和喜歡的東西。

回答

3
  1. 套接字API肯定是線程安全的在每個插槽的基礎...即只要任何給定的插座僅由一個線程訪問,其他線程可以在同一時間內訪問其它插槽沒有任何問題。讓多個線程同時訪問同一個套接字可能或者可能不是「線程安全的」(對於一些線程安全的定義),但無論如何都不推薦使用,因爲最終的行爲不容易預測。 (例如兩個線程同時在同一個套接字上調用recv(),哪個線程將從傳入的TCP流獲得哪些字節?上帝只知道)

  2. 如果您使用阻塞I/O,然後檢查在調用send()之前使用poll/select()並不是非常有用,因爲即使select()指示您在傳出緩衝區中有空間,也可能會阻塞send()。 (例如,如果緩衝區中有32個字節的空間,然後嘗試發送64個字節,send()將會被阻止)。 select()和poll()與非阻塞I/O結合使用會更有用。

  3. 我不太確定Linux套接字中零拷貝的狀態,但Wikipedia article似乎表明Linux只在使用sendfile(),sendfile64()或splice時執行零拷貝()調用。鑑於現代CPU,無論如何,我懷疑這一切都非常重要 - 除了最高性能的程序之外,所有程序都將具有足夠的CPU週期來複制網絡數據;網絡接口本身的速度將成爲瓶頸。

  4. 多個套接字不會爲您提供比單個套接字更好的帶寬利用率;如果您足夠快地將數據通過網絡連接,單個套接字可輕鬆飽和網絡連接。特別是多個TCP連接通常會帶來比單個TCP連接更差的帶寬利用率,因爲每個TCP連接都會產生自己的傳輸開銷,更糟糕的是,多個TCP連接將爭奪帶寬,並且在某些時候開始導致對方丟棄數據包,他們會通過降低發送速率來減少擁塞來應對。

  5. 我無法回答這個問題,在MacOS/X活動監視器下將顯示網絡帶寬使用情況。

1

傑里米的第3點有點不準確。隨着多個高速網絡接口和大量數據移動,零拷貝變得更加重要。花費在內存中複製緩衝區的時間會影響吞吐量和延遲。異步IO和分散/聚集支持對於高速聯網系統至關重要。