2017-01-27 32 views
4

我剛學Python和不循環與多線程很多經驗研究。我正嘗試通過請求session.post方法發送一些json。這在我需要運行字典的許多for循環的bottem函數中調用。的Python多線程一個具有有限線程

有沒有辦法讓使用並聯此運行?

我也有限制我的線程數,否則來電後得到阻止,因爲他們畢竟對方快。幫助將不勝感激。

def doWork(session, List, RefHashList): 
    for itemRefHash in RefHashList: 
     for equipment in res['Response']['data']['items']: 
      if equipment['itemHash'] == itemRefHash: 
       if equipment['characterIndex'] != 0: 
        SendJsonViaSession(session, getCharacterIdFromIndex(res, equipment['characterIndex']), itemRefHash, equipment['quantity']) 

回答

3

首先,以不同的方式組織代碼可以在不增加線程複雜性的情況下提高速度。

def doWork(session, res, RefHashList): 
    for equipment in res['Response']['data']['items']: 
     i = equipment['itemHash'] 
     k = equipment['characterIndex'] 
     if i in RefHashList and k != 0: 
      SendJsonViaSession(session, getCharacterIdFromIndex(res, k), i, equipment['quantity']) 

要下手,我們將查找equipment['itemHash']equipment['characterIndex']只有一次。

而不是明確地遍歷RefHashList,你可以使用in操作。這將循環移動到Python虛擬機中,速度更快。

而不是嵌套if - 條件,您可以使用一個條件使用and

注:我已刪除未使用的參數List,並與res取而代之。編寫只對它們給出的參數起作用的函數,而不是全局變量,這是一種很好的做法。

其次,多少額外的性能,你需要什麼? SendJsonViaSession電話之間平均有多少時間,以及這段時間在電話被阻止之前有多少時間?如果這些數字之間的差異很小,則可能不值得實施一個線程發件人。

第三,標準Python實現的一個設計特性是隻有一次線程可以執行Python字節碼。所以不能確定線程會提高性能。

編輯:

有幾種方法在Python並行運行的東西。有使用進程的multiprocessing.Pool,使用線程的multiprocessing.dummy.ThreadPool。從Python 3.2開始,有concurrent.futures,它可以使用進程或線程。

的事情是,他們都不具有速率限制。所以你可能會因爲打太多的電話而被阻止。 每次您撥打SendJsonViaSession時,都必須以某種方式保存當前時間,以便所有進程或線程都可以使用它。在每次通話之前,您都必須閱讀該時間,並等待它與最後一次通話太接近。

EDIT2:

如果到SendJsonViaSession通話僅在0.3秒,你應該能夠做到3個呼叫/秒順序。但是你的代碼只能做1次/秒。這意味着速度限制是在別的地方。您必須使用代碼profile才能看到問題出在哪裏。

+0

太棒了。感謝您提供快速而翔實的幫助。我可以在10秒內打250個電話,否則油門開始,我被阻止。現在我在10秒內發送大約10個電話。所以可能會有改進的潛力。 –

+0

@LeoldeWire對'SendJsonViaSession'的調用實際上需要多長時間? –

+0

〜0.3秒我會說 –