2

背景線程或Multiprocessing如何與遞歸一起工作?

我有點新開發,並有一個一般的Python /編程問題。如果您有一種遞歸方法,那麼啓用多線程或多處理的內容是什麼?我已經做了一些簡單的閱讀和一些例子,但他們似乎應用新代碼的語法(而不是非常密集的cpu任務),我更想知道如何重新設計現有代碼來做到這一點?

說我有什麼那是CPU密集型(基本保持增加了自己,直到極限命中):

def adderExample(sum, number): 
    if sum > 1000: 
     print 'sum is larger than 10. Stoping' 
    else: 
     sum = sum + number 
     print sum 
     number = number + 1 
     adderExample(sum, number) 


adderExample(0,0) 

問題(S)/雖然過程

我將如何處理這使它運行得更快,假設我有多個內核可用(我希望它最終希望它跨越機器,但我認爲這是hadoop的一個特殊問題,所以我會保持這個例子只有一個系統與多個CPU)?看起來線程化並不是最好的選擇(因爲產生新線程需要花費時間),如果這是真的,我應該只關注多處理?如果是這樣,可以將遞歸分割爲不同的cpu(我假設的排隊,然後在完成後重新加入)?我可以爲每個進程創建多個線程,而不是通過多個cpu分割這些進程?最後,遞歸深度是否限制了整體限制,還是基於線程/過程,如果多處理/線程解決了這個限制呢?

另一個問題(相關)如何通過暴力試圖編碼(rsa,無線密鑰等)代碼克服了這個問題?我假設他們以某種方式在多個cpu上調整他們的數學過程。這個或任何建立我理解的例子都很棒。

任何提示/建議將是偉大的

謝謝!

+0

一般來說,進程需要更多的時間和開銷產生比線程。線程使用與啓動程序相同的內存空間。進程必須創建新的內存開銷。使用線程技術,您還可以輕鬆地併入信息結構的共享而不需要複製信息結構,但是如果不使用基於OS(或其他)的「共享內存」IPC實現,就無法輕鬆地通過多個進程來實現這一點。 – g19fanatic

回答

4

這樣的循環根本不會受益於線程。考慮你正在做一系列的增加,其中間值取決於以前的迭代。這不能被並行化,因爲線程會跺腳對方的值並覆蓋事物。您可以鎖定數據,以便一次只能有一個線程處理數據,但是會失去多線程處理數據的好處。

當他們有獨立的數據集時,線程工作效果最佳。例如一個圖形渲染器就是一個很好的例子。每個線程渲染較大圖像的一個子集 - 它們可以共享紋理/頂點/顏色/等等數據的常見數據源,但是每個線程都有自己的一小部分工作總圖像,並且不會觸及圖像的其他區域。無論線程#1在其小部分像素上做什麼都不會影響線程#2在圖像中的其他位置執行的操作。

對於您的相關問題,密碼破解是線程/多處理有意義的另一個示例。每個線程都會自行測試多個可能的密碼,以針對一個常見的「被破解」列表。一個線程正在做的事情不會影響其他任何cracker線程,除非你得到一個匹配,這可能意味着所有線程因作業「完成」而中止。

一旦線程相互依賴,就失去了多線程的許多好處。他們會花更多的時間等待對方完成比完成實際工作花費的時間。當然,這並不是說你永遠不應該使用線程。有時候,多線程是有意義的,即使它們是相互依賴的。例如。一個圖形線程+音效線程+動作處理器線程+ A.I.計算線程等...在遊戲中。每個人在名義上都相互依賴,但是當聲音線程忙於爲玩家剛剛開槍時的槍聲產生爆炸+彈跳音頻時,a.i.線程正在計算遊戲的小怪正在做什麼,圖形線程正在後臺繪製一些雲,等等......

+0

我想我多瞭解一點,謝謝Marc。爲了進一步理解,我理解了使用字典並排隊的密碼破解程序,但如果破解程序生成自己的密碼(不是基於字典的例如a,b,c,... aa,ab,ac等),該怎麼辦?我的理解是否正確,如果我認爲他們不能多處理組合的生成(但是多進程實際上試圖使用密碼,因爲組合被放入隊列中)? – Lostsoul

+0

您可以並行化進程,**如果您可以將任務分解。例如對於數字序列密碼的列​​表(1,2,3,4,5等),你可以將它分成2個線程(一個是evens,一個是賠率),等等......只要你可以使每個線程都有自己獨立的整體列表部分,那就沒問題了。但是如果你有5個線程,但將工作量分成4塊,那麼你會浪費一些時間來重複工作。 –

1

線程kinda sorta意味着多個堆棧,遞歸單個堆棧。也就是說,如果你到達左迴歸,右迴歸部分,並決定爲子問題產生線程(如果當前線程數爲「低」)並進行直線遞歸,否則可以組合概念。

但是對於這種模式,普通的Python並不是一種好語言。 Python線程都運行在同一個解釋器硬件線程上,所以你不會真正獲得任何多處理器的好處。

0

由於防止多線程並行執行Python代碼的「全局解釋器鎖」,Phunctor是正確的,線程庫對於並行化這類問題是一個糟糕的選擇。

雖然線程庫可能非常有用,但每個線程的代碼花費了很多時間等待I/O發生。因此,例如,如果您正在實現必須打開磁盤或等待網絡響應的服務器,則在每個線程中爲請求提供服務可能非常高效,因爲線程庫可以支持那些不等待的服務器/ O,從而最大限度地利用Python解釋器。 (在一個線程中,你必須使用一個嚴格的循環來檢查你的I/O請求的狀態,當負載變高時這往往是浪費的。)