簡體   English   中英

這是python客戶端的高效TCP / IP套接字循環嗎?

[英]Is this an efficient TCP/IP socket loop for a python client?

我正在連接到一個服務器,它將向我發送需要按行處理的流數據。 所以我必須解析各行,然后處理每一行。 以下代碼似乎工作正常,但我想知道是否有任何標准的設計模式來做這種類型的事情。 或者這是要走的路?

隊列是否會引入任何嚴重的開銷? 我需要它盡可能快速有效,這也是我偏離像扭曲的圖書館的原因。

import socket, multiprocessing

def receive_proc(s, q):
    data = ''
    while True:
        data += s.recv(4096)
        if '\n' in data:
            lines = data.split('\n')[:-1]
            for line in lines:
                if len(line) > 0:
                    q.put(line)
                    data = data.replace(line+'\n', '', 1)

q = multiprocessing.Queue()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 1234))

p = multiprocessing.Process(target=receive_proc, args=(s,q))
p.start()

while True:
    line = q.get()

    # do your processing here

當然有充分的理由希望遠離扭曲之類的東西,但我不認為效率是其中之一 - 我懷疑他們更有可能以正確的方式進行優化。 性能是一個棘手的野獸,通常瓶頸並不是你想到的,這就是為什么你需要在你可以正確優化之前進行分析。 例如,框架可能已經努力將更多的代碼推送到C擴展中,這肯定有助於提高性能。 如果性能是你的關鍵動力,第三方的東西可能是更安全的選擇。 此外,對於使用其他人已經針對各種不同的用例和環境進行測試和調整的代碼存在很大的爭議 - 如果你最終重新發明過多的輪子,那么總是存在可能缺少一些輻條的風險。

但是,您需要做的事情看起來非常簡單,因此安裝和學習框架的開銷以及向代碼添加另一個運行時依賴項的開銷可能是不合理的。 此外,如果你主要是IO綁定,那么燒掉一些額外的CPU進行處理並不會產生太大的影響。 我當然已經避免了過去有時會扭曲的事情,因為我知道自己編寫它會更快(就我的時間而言)並且性能會“足夠好”。 我總是發現twisted的回調系統使得調試有點棘手 - 例如,獲取錯誤消息可能有點令人擔憂。 這絕不是不可能的,許多人非常成功地使用它,但我個人覺得它太“繁瑣”,無法為簡單的任務辯護。

在這種情況下,我認為你將接收和處理分成他們自己的進程的想法可能是錯誤的經濟 - 從套接字接收數據非常快,如果你在純Python中進行大量處理,那么可能是主導表現因素。 但是,如果不知道你正在做什么處理,我不能肯定地說。 如果它將耗費大量時間和/或CPU,並且您可以獨立於先前的行處理每一行,那么它可能是合理的,但您可能希望將處理集中到一組工作進程。 根據您現有的代碼,這非常簡單 - 只需將主進程設置為接收器而不是“從屬”,並創建一個共享Queue的工作池。 每個工人都會經歷一個循環,選擇下一個項目並生成結果。 無論多長時間都沒關系,他們只需獲得下一個項目( Queue將為您處理)。

但是,如果您的處理循環也主要是IO綁定(例如寫入文件),那么您可能會發現單個進程實際上比將所有內容推送到管道上的開銷要好。 這取決於許多因素,包括您的CPU架構(某些系統使CPU內核之間的傳輸比其他系統更昂貴),但最終您不希望使用多個進程,除非您非常有信心它將為您帶來性能提升。

無論如何,如果循環 IO綁定的,您可能會發現一個具有非阻塞IO的進程是可行的。 你可以使用Python的select模塊自己做,或者你可以使用像eventletgevent這樣的庫來清楚

不相關 - 你從緩沖區中剝離啟動的方法是非常低效的 - 你不需要使用replace()你可以只使用你現有的split() ,如下所示:

while True:
    data += s.recv(4096)
    if '\n' in data:
        lines = data.split('\n')
        for line in lines[:-1]:
            if len(line) > 0:
                q.put(line)
        data = lines[-1]

暫無
暫無

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

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