2017-10-14 51 views
0

現在我有以下情況:如何讓多處理.Pool()中的某些進程從Python打印到Python中的stdout?

def take_time(time): 
     sleep(time) 
     print("Took %d seconds!" %time) 

    def multip(num_cores, data): 
     p = multiprocessing.Pool(num_cores) 
     p.map(take_time, data) 
     end_time = time() 
     print("total time taken: %d" %(end_time - start_time)) 

假設num_cores = 2data = (1,1,3)

>>> multi(4, data) 
Took 1 seconds! 
Took 1 seconds! 
Took 3 seconds! 

這怎麼能渲染,以便一次只有一個進程轉到stdout? 只要沒有兩個印刷品同時印刷,哪個印刷過程並不特別重要。假設我們首先打印對應於的進程。然後,所需的輸出將

>>> multi(4, data) 
Took 1 seconds! 
Took 3 seconds! 

我猜有剛有一個更細齒的工具,而map()。謝謝!

+2

如果您有三個輸入,您爲什麼只希望得到兩個輸出? –

+1

而不是從'take_time'內打印,你可以返回一個值給你的主線程/進程,並在那裏打印它。 – 101

回答

0

一種策略是隻從一個正在運行的線程寫入,並讓其他線程輸出到隊列中。這樣做需要您的主線程異步啓動其他線程(例如,使用map_async),然後從隊列中讀取,直到完成。以你的榜樣,你會做這樣的事情:

q = multiprocessing.Queue() 

def take_time(time): 
    sleep(time) 
    q.put("Took %d seconds!" %time) 

def multip(num_cores, data): 
    p = multiprocessing.Pool(num_cores) 
    start_time = time() 
    result = p.map_async(take_time, data) 

    while not result.ready(): 
     print q.get() 

    end_time = time() 
    print("total time taken: %d" %(end_time - start_time)) 

有關如何這可以應用於現實世界的例子,check out the codedocker-compose log命令,其內容可能多個集裝箱過程的輸出並將它們組合成一個單一的流。

+0

注意:只要使用'imap'或'imap_unordered'就可以簡化它;使返回值爲要打印的字符串,並且您不需要自己管理'Queue'。在p.imap_unordered(take_time,data):print(result)'中得到結果,並將'q.put'改爲'return'Took%d seconds!「 %time' – ShadowRanger

+0

那是真的 - 使用隊列解決了線程在一段時間內產生0個或更多輸出字符串的一般情況,但如果您只需要在執行結束時打印並可以通過'return '。 – avigil

相關問題