看来,当从multiprocessing.Pool进程引发异常时,没有堆栈跟踪或任何其他指示其已失败的迹象。例:
from multiprocessing import Pool
def go():
print(1)
raise Exception()
print(2)
p = Pool()
p.apply_async(go)
p.close()
p.join()
打印1并静默停止。有趣的是,引发BaseException可以工作。有什么方法可以使所有异常的行为与BaseException相同?
我有一个合理的解决方案,至少用于调试目的。我目前没有一个可以在主要流程中引发异常的解决方案。我的第一个想法是使用装饰器,但是您只能腌制在模块顶层定义的函数,所以没错。
取而代之的是一个简单的包装类和一个Pool子类,将其用于apply_async
(因此apply
)。我将map_async
作为练习留给读者。
import traceback
from multiprocessing.pool import Pool
import multiprocessing
# Shortcut to multiprocessing's logger
def error(msg, *args):
return multiprocessing.get_logger().error(msg, *args)
class LogExceptions(object):
def __init__(self, callable):
self.__callable = callable
def __call__(self, *args, **kwargs):
try:
result = self.__callable(*args, **kwargs)
except Exception as e:
# Here we add some debugging help. If multiprocessing's
# debugging is on, it will arrange to log the traceback
error(traceback.format_exc())
# Re-raise the original exception so the Pool worker can
# clean up
raise
# It was fine, give a normal answer
return result
class LoggingPool(Pool):
def apply_async(self, func, args=(), kwds={}, callback=None):
return Pool.apply_async(self, LogExceptions(func), args, kwds, callback)
def go():
print(1)
raise Exception()
print(2)
multiprocessing.log_to_stderr()
p = LoggingPool(processes=1)
p.apply_async(go)
p.close()
p.join()
这给了我:
1
[ERROR/PoolWorker-1] Traceback (most recent call last):
File "mpdebug.py", line 24, in __call__
result = self.__callable(*args, **kwargs)
File "mpdebug.py", line 44, in go
raise Exception()
Exception
我主要是为技术精明的人编写一个小工具,例如程序员、工程师等,因为这些工具通常是快速的,随着时间的推移,我知道会有未处理的异常,用户不会介意。我希望用户能够向我发送回溯,这样我就可以检查发生了什么,并可能改进应用程序。 我通常做wxPython编程,但我最近做了一些Java。我已经将
异常检测与处理 [MCE] mce=off 彻底禁用MCE(CONFIG_X86_MCE) [MCE] mce=dont_log_ce 不为已纠正错误(corrected error)记录日志。 [MCE] mce=容错级别[,超时] 容错级别(还可通过sysfs设置): 0 在出现未能纠正的错误时panic,记录所有已纠正的错误 1(默认值) 在出现未能纠正的错误时panic或SIGBUS,记录
问题内容: 我有一个生成器和一个使用它的函数: 如果生成器引发异常,我想在使用者函数中处理该异常,然后继续使用迭代器,直到耗尽为止。请注意,我不想在生成器中有任何异常处理代码。 我想到了类似的东西: 但这对我来说看起来很尴尬。 问题答案: 这也是我不确定是否正确/优雅处理的事情。 我要做的是从生成器中获取一个,然后将其提升到其他位置。喜欢: 这样,我仍然继承了Exception而没有引发它,这将导
我有一个图像路径列表,我想在进程或线程之间划分,以便每个进程处理列表的某些部分。处理包括从磁盘加载图像,进行一些计算并返回结果。我正在使用Python 2.7 下面是我如何创建辅助进程 我所面临的问题是,当我在initializer函数中记录初始化时间时,我知道worker不是并行初始化的,而是每个worker都以5秒的间隔初始化,下面是供参考的日志 我尝试过使用将同时启动辅助线程 我知道Wind
你有什么想法吗??我不知道该怎么办了:/ 13449[MyScheduler_Worker-1]错误org.quartz.core.jobrunshell-Job group1.jobreport引发了一个未处理的异常:java.lang.nullpointerexception at com.changes.bean.reportsbean.createpdfCriticalChanges(re
让我们考虑一个<代码>父< /代码>类,它只包含一个<代码>整数< /代码>属性。我用一个空变量创建了6个父类对象。然后我将这些对象添加到列表中。 我想通过属性的值检索相应的对象。我使用了Java8流。 但是我得到了,所以我编辑了代码: 但是如果任何对象为null,我想抛出一个异常。如果列表中没有对象为null,那么我想从列表中检索相应的对象。 如何使用Java 8 Streams使用一条语句实现