2013-08-31 18 views
0

不知道你能幫忙嗎?我是Python新手,正在嘗試將一段簡單的代碼並行計算(跨多個CPU內核)......我知道這很蹩腳,但它似乎是一段合理的代碼,可以學習Python線程等Python - 多進程代碼成功返回結果到隊列,但代碼停止

我已經成功地設法使用線程運行代碼,但我現在正在調查進程(es)。

下面的代碼運行良好,直到我收集結果。我試過使用eclipse &進行調試,並且發現我用來從outputQueue中移除項目的While循環似乎在3次迭代後仍然存在,所以代碼從未到達輸出結果的階段。

任何想法/建議/幫助將不勝感激。

非常感謝

克雷格 ------代碼

from multiprocessing import Process, Queue 

# return true if number is prime, else false 
def calcPrime(number):  
    divisor=2 
    if number%2==0: 
     return False 

    numberIsPrime=True 
    while divisor*divisor <= number: 
     if number % divisor == 0: 
      numberIsPrime = False 
      break 
     divisor = divisor + 1 
    return numberIsPrime 

# generate list of primes 
def generatePrimes(minimum, maximum): 
    return [num for num in range(minimum,maximum) if calcPrime(num)==True] 

def workerThread(output, mn, mx): 
    primelist=generatePrimes(mn,mx) 
    output.put(primelist) 

def main(): 
    outputQueue=Queue() 

    t=[] 
    t.append(Process(target=workerThread, args=(outputQueue, 1,25000))) 
    t.append(Process(target=workerThread, args=(outputQueue, 25001, 50000))) 
    t.append(Process(target=workerThread, args=(outputQueue, 50001, 75000))) 
    t.append(Process(target=workerThread, args=(outputQueue, 75001, 100000))) 

    #start all threads 
    for idx in range(len(t)): 
     t[idx].daemon=True 
     t[idx].start() 

    #wait for all process threads to complete 
    for p in t: 
     p.join() 
    print("Processes finished") 

    # gather all results 
    l=[] 
    while True: 
     try: 
      l+=outputQueue.get() # Code seems to stick here after about 3-4 iterations 
     except: 
      break 

    #print out our lovely primes 
    for idx in range(len(l)): 
     print (str(l[idx]))  

# standard code   
if __name__ == '__main__': 
    main() 
+0

'如果calcPrime(num)== True'比較是多餘的。只需使用'如果calcPrime(num)'。另外,當比較'True','False'或'None'時,你應該使用'is'運算符:'如果calcPrime(num)是真的'。無論何時你只想知道某些東西的「真值」,只需使用「not」來檢查「false」並將對象本身變爲「true」。 – Bakuriu

回答

1

此代碼是一個無限循環:

l=[] 
while True: 
    try: 
     l+=outputQueue.get() # Code seems to stick here after about 3-4 iterations 
    except: 
     break 

get()的呼叫阻塞,即它會等到你送東西。 在你的情況下,當進程結束循環時,會再次調用get()永不返回。

既然你知道的進程數,你可以簡單地做一些get() S:

l = sum((outputQueue.get() for _ in range(t)), []) 

如果一個進程可以把一個變量多項成果,那麼你就可以發送一個哨兵值時工人完成(例如None)。收集輸出的過程可以計算它接收到多少哨兵,並最終停止查詢隊列。