gpt4 book ai didi

python - 为什么 ProcessPoolExecutor 和 Pool 会因 super() 调用而崩溃?

转载 作者:太空狗 更新时间:2023-10-30 00:58:15 27 4
gpt4 key购买 nike

<强>1。为什么以下使用 concurrent.futures 模块的 Python 代码会永远挂起?

import concurrent.futures


class A:

def f(self):
print("called")


class B(A):

def f(self):
executor = concurrent.futures.ProcessPoolExecutor(max_workers=2)
executor.submit(super().f)


if __name__ == "__main__":
B().f()

调用引发了一个不可见的异常[Errno 24] Too many open files(要查看它,请将 executor.submit(super().f) 行替换为print(executor.submit(super().f).exception())).

但是,将 ProcessPoolExecutor 替换为 ThreadPoolExecutor 会按预期打印“called”。

<强>2。为什么以下使用 multiprocessing.pool 模块的 Python 代码会引发异常 AssertionError: daemonic processes are not allowed to have children

import multiprocessing.pool


class A:

def f(self):
print("called")


class B(A):

def f(self):
pool = multiprocessing.pool.Pool(2)
pool.apply(super().f)


if __name__ == "__main__":
B().f()

但是,将 Pool 替换为 ThreadPool 会按预期打印“called”。

环境:CPython 3.7,MacOS 10.14。

最佳答案

concurrent.futures.ProcessPoolExecutormultiprocessing.pool.Pool 使用 multiprocessing.queues.Queue 将工作函数对象从调用者传递到工作进程,Queue 使用 pickle 模块进行序列化/反序列化,但未能正确处理子类实例绑定(bind)的方法对象:

f = super().f
print(f)
pf = pickle.loads(pickle.dumps(f))
print(pf)

输出:

<bound method A.f of <__main__.B object at 0x104b24da0>>
<bound method B.f of <__main__.B object at 0x104cfab38>>

A.f 变为 B.f,这实际上在工作进程中创建了无限递归调用 B.fB.f

pickle.dumps 利用绑定(bind)方法对象的 __reduce__ 方法,IMO,its implementation , 没有考虑这种场景,它不关心真正的 func 对象,而只是尝试从实例 self obj (B() ) 的简单名称 (f),结果是 B.f,很可能是一个错误。

好消息是,我们知道问题出在哪里,我们可以通过实现我们自己的缩减函数来解决它,该函数尝试从原始函数 (A.f) 和实例 obj 重新创建绑定(bind)方法对象(B()):

import types
import copyreg
import multiprocessing

def my_reduce(obj):
return (obj.__func__.__get__, (obj.__self__,))

copyreg.pickle(types.MethodType, my_reduce)
multiprocessing.reduction.register(types.MethodType, my_reduce)

我们可以这样做,因为绑定(bind)方法是一个描述符。

ps:我已经备案a bug report .

关于python - 为什么 ProcessPoolExecutor 和 Pool 会因 super() 调用而崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56609847/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com