多处理时不调用回调

zel*_*ell 5 python asynchronous multiprocessing

我花了一整天时间来调试以下代码。这是关于多处理的。请看一下。

import numpy as np
import multiprocessing as mp


def printHello(x):
    print "ENTERING: printHello"
    time.sleep(2)
    print "QUITTING: printHello"
    return 'hello '+x

def log_result(result):
    print "ENTERING: log_result"
    time.sleep(2)
    print "QUITTING: log_result"

def main_multi():
    pool = mp.Pool()
    for i  in range(3):
        pool.apply_async(printHello, args=(i, ), callback=log_result)
    pool.close()
    pool.join()

if __name__=='__main__':
    print "ENTERING __main__"
    main_multi()
    print "QUITTING __main__"
Run Code Online (Sandbox Code Playgroud)

我以为我会在输出行中得到“退出:printHello”,“进入:log_result”和“退出:printHello”。对我来说,奇怪的是,主程序停止时,printHello尚未完成(没有打印出“ hello”);“ pool.join”语句似乎以某种方式被忽略。也许上面的“回调”或“ apply_async”无法按我预期的方式工作。任何的想法?

我的控制台的输出是:

ENTERING __main__
ENTERING: printHello
ENTERING: printHello
ENTERING: printHello
QUITTING __main__ 
Run Code Online (Sandbox Code Playgroud)

[编辑]有趣的是,如果我删除“ time.sleep(2)”部分,则会得到

ENTERING __main__
ENTERING: printHello
QUITTING: printHello
ENTERING: printHello
QUITTING: printHello
ENTERING: printHello
QUITTING: printHello
QUITTING __main__
Run Code Online (Sandbox Code Playgroud)

但这仍然不能解决所有问题。因为未打印出“ helloPrint”中的“ hello”,而在apply_async之后却有一个pool.join。

[Edit2]我只添加了“导入时间”。症状仍然存在:pool.join应该阻塞,直到进程终止,但实际情况并非如此。

Blc*_*ght 5

您尚未导入time模块,因此time.sleep导致工作进程出错的调用。这就是为什么您没有收到"QUITTING"消息,也没有调用回调的原因。

如果您解决了该问题,则在尝试生成返回值时,仍然会在工作程序中遇到错误。您正在将x传递给整数的整数相加,该整数的"hello"定义不明确。您需要将整数转换为字符串才能使字符串串联工作。

  • 如果保留池的 apply_async 方法返回的 AsyncResult 值,您将能够通过调用其 get 方法来获取异常(这会引发工作进程中捕获的异常)。Python 3 的 `concurrent.futures` 模块做得更好一些,因为在正常和错误情况下,您可以使用 `Future` 对象本身来调用为异步调用设置的回调。 (2认同)