简体   繁体   English

当 function 是 lambda 或嵌套的 function 时,concurrent.futures.ProcessPoolExecutor 挂起

[英]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.

相关问题 将带有对象的 function 传递到 concurrent.futures.ProcessPoolExecutor()? - Pass function with objects into concurrent.futures.ProcessPoolExecutor()? 如何在 concurrent.futures.ProcessPoolExecutor 期间将变量 output 存储在 function 中 - How to store the variables output inside a function during concurrent.futures.ProcessPoolExecutor from concurrent.futures 如何将多个参数传递给由 concurrent.futures.ProcessPoolExecutor 中的 executor.map() 迭代的函数 - How to pass several parameters to a function which is iterated by executor.map() from concurrent.futures.ProcessPoolExecutor Python 上的 `concurrent.futures.ProcessPoolExecutor` 从文件开头而不是定义的函数运行 - `concurrent.futures.ProcessPoolExecutor` on Python is ran from beginning of file instead of the defined function 使用`concurrent.futures.ProcessPoolExecutor`时获取当前进程ID - Get current process id when using `concurrent.futures.ProcessPoolExecutor` concurrent.futures.ProcessPoolExecutor() 中的共享变量 python - Shared variable in concurrent.futures.ProcessPoolExecutor() python 使用初始化启动 concurrent.futures.ProcessPoolExecutor? - Launch concurrent.futures.ProcessPoolExecutor with initialization? 为什么 concurrent.futures.ProcessPoolExecutor() 跳过迭代? - Why is concurrent.futures.ProcessPoolExecutor() skipping iterations? 当多个子进程使用 `concurrent.futures.ProcessPoolExecutor` 访问时,`queue.Queue` 是线程安全的吗? - Is `queue.Queue` thread-safe, when accessed by several subprocesses using `concurrent.futures.ProcessPoolExecutor`? 在 Python 中使用 concurrent.futures.ProcessPoolExecutor 时为每个进程创建一个单独的记录器 - Create a separate logger for each process when using concurrent.futures.ProcessPoolExecutor in Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM