[英]concurrent.futures.ProcessPoolExecutor hangs when the function is a lambda or nested function
Can anyone provide insight into why using lambda or a nested function ( f
) would make concurrent.futures.ProcessPoolExecutor
hang in the following code example?谁能提供洞察为什么使用 lambda 或嵌套的 function (
f
) 会使concurrent.futures.ProcessPoolExecutor
在以下代码示例中挂起?
import concurrent.futures
def f2(s):
return len(s)
def main():
def f(s):
return len(s)
data = ["a", "b", "c"]
with concurrent.futures.ProcessPoolExecutor(max_workers=1) as pool:
# results = pool.map(f, data) # hangs
# results = pool.map(lambda d: len(d), data) # hangs
# results = pool.map(len, data) # works
results = pool.map(f2, data) # works
print(list(results))
if __name__ == "__main__":
main()
Long story short, Pool/ProcessPoolExecutor both must serialize everything before sending 'em to the workers.长话短说,Pool/ProcessPoolExecutor 在将它们发送给工作人员之前都必须序列化所有内容。 Serializing (also sometimes called pickling) actually is the process in which the name of a function is saved, to only be imported again once Pool wants to have access to it.
序列化(有时也称为酸洗)实际上是保存 function 名称的过程,只有在 Pool 想要访问它时才能再次导入。 For this process to work, the function has to be defined at the top-level since nested functions are not importable by the child which is the reason for the following error to show up:
为了使这个过程正常工作,function 必须在顶层定义,因为嵌套函数不能由子级导入,这是出现以下错误的原因:
AttributeError: Can't pickle local object 'MyClass.mymethod.<locals>.mymethod'
To avoid this problem, there some solutions out there that I've not found reliable.为了避免这个问题,有一些我认为不可靠的解决方案。 If you're flexible on using other packages, pathos is an alternative that actually works .
如果您可以灵活地使用其他包,那么pathos是一个实际可行的替代方案。 For instance, the following won't hang:
例如,以下内容不会挂起:
import pathos
import os
class SomeClass:
def __init__(self):
self.words = ["a", "b", "c"]
def some_method(self):
def run(s):
return len(s)
return list(pool.map(run, self.words))
pool = pathos.multiprocessing.Pool(os.cpu_count())
print(SomeClass().some_method())
and it will indeed print它确实会打印
[1, 1, 1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.