多处理中的error_callback.Pool在Python 2中的apply_async?

时间:2015-01-16 15:06:14

标签: python python-2.7 python-3.x multiprocessing

apply_async类的函数multiprocessing.Pool Python 3 中有参数error_callback。但 Python 2 中缺少此参数。

在Python 2中有没有任何技巧可以实现相同的功能?理想情况下,我想编写在Python 2和3中运行的代码。

2 个答案:

答案 0 :(得分:2)

我还没有尝试过python3。但对我来说,为了捕捉子进程中的错误,我将在子进程中运行的函数放在

import traceback


try:
    your code that can make error
except Exception as e:
    print e
    return False, traceback.format_exc()
else:
    return True, result

这样我就知道出了什么问题。

编辑:我将返回格式更改为OP的注释,以便子进程返回元组(is_success, result or error traceback message )

因此主进程将首先读取标志is_success,然后相应地处理第二个参数。

答案 1 :(得分:-1)

TL; DR

不使用额外的参数来返回,而是使用successful()为您提供的AnycResult objects方法。这就是它的用途。

说明

调用apply_async返回AsyncResult对象。这些对象有一个名为successful()的方法,它将告诉您目标进程是否通过异常退出。调用successful()将返回true或false,具体取决于子进程是否以异常退出。这是一个例子:

import multiprocessing

def good_func(arg):
    arg += 1
    return arg

def bad_func(arg):
    arg += 1
    raise Exception # force an exception to be raised
    return arg

pool = multiprocessing.Pool()

good_result = pool.apply_async(good_func, (1,))
bad_result = pool.apply_async(bad_func, (1,))

pool.close()
pool.join()

print(good_result.successful()) # prints True
print(bad_result.successful())  # prints False

此代码返回:

  


  假

如果对successfull()的调用返回false,则可以添加调用清理或错误处理代码的条件表达式。

此外,如果需要回溯,可以将子进程函数的主体包装在try / except块中,并在发生异常时返回跟踪的字符串版本。它可能看起来像这个版本的bad_func

import sys
import traceback
import multiprocessing

def good_func(arg):
    arg += 1
    return arg

def bad_func(arg):
    try:
        arg += 1
        raise Exception
        return a
    except Exception as error:
        # capture the exception and bundle the traceback
        # in a string, then raise new exception with the string traceback
        raise Exception("".join(traceback.format_exception(*sys.exc_info())))

pool = multiprocessing.Pool()

good_result = pool.apply_async(good_func, (1,))
bad_result = pool.apply_async(bad_func, (1,))

pool.close()
pool.join()

print(good_result.successful()) # prints True
print(good_result.get())        # prints good result
print(bad_result.successful())  # prints False
print(bad_result.get())         # prints traceback

此代码生成此输出:

  


  2
  假
  追溯(最近的呼叫最后):
  文件" async_err.py",第29行,在   打印(bad_result.get())
  文件" /user/peteoss/encap/Python-2.7.6/lib/python2.7/multiprocessing /pool.py" ;,第554行,在获取中   提高self._value
  例外:回溯(最近一次呼叫最后):
  文件" async_err.py",第13行,在bad_func中   提出异常
  例外

您应该注意以下几点:

  1. 您将获得两个回溯:一个来自失败的被调用者get(),第二个回溯是捆绑到子进程中的字符串中的回溯。

  2. 如果将子进程函数包装在try / except块中,则需要在处理异常时重新添加异常,否则get()将返回false。

  3. AsyncResult.successful()AsyncResult.get()方法在所有具有多处理库的CPython版本中都可用,因此该方法符合编写与版本无关的代码的要求。

    < / LI>