2017-10-14 62 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

相关问题