python - 多处理和垃圾收集

标签 python unix garbage-collection multiprocessing

在py2.6+中,multiprocessing模块提供了一个Pool类,所以可以这样做:

class Volatile(object):
    def do_stuff(self, ...):
        pool = multiprocessing.Pool()
        return pool.imap(...)

但是,对于 2.7.2 的标准 Python 实现,这种方法很快会导致“IOError:[Errno 24] 打开的文件太多”。显然 pool 对象永远不会被垃圾收集,因此它的进程永远不会终止,累积内部打开的任何描述符。我认为这是因为以下工作:

class Volatile(object):
    def do_stuff(self, ...):
        pool = multiprocessing.Pool()
        result = pool.map(...)
        pool.terminate()
        return result

我想保留 imap 的“惰性”迭代器方法;在这种情况下,垃圾收集器如何工作?如何修复代码?

最佳答案

最后,我最终传递了 pool 引用并在 pool.imap 迭代器完成后手动终止它:

class Volatile(object):
    def do_stuff(self, ...):
        pool = multiprocessing.Pool()
        return pool, pool.imap(...)

    def call_stuff(self):
        pool, results = self.do_stuff()
        for result in results:
            # lazy evaluation of the imap
        pool.terminate()

以防将来有人偶然发现此解决方案:chunksize 参数在 Pool.imap非常重要(与普通 Pool.map,无关紧要)。我手动设置它,以便每个进程接收 1 + len(input)/len(pool) 作业。将它保留为默认值 chunksize=1 给我的性能就好像我根本不使用并行处理一样……不好。

我想使用有序 imap 与有序 map 并没有真正的好处,我个人更喜欢迭代器。

关于python - 多处理和垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9959598/

相关文章:

python-3.x - 了解 CPython 垃圾收集世代

python - 如何检查for循环是否在python中完全结束?

python - 谷歌 API 服务帐户。即使使用域范围委派访问也只能看到服务帐户驱动器

unix - 在变量中使用 sed 中的特殊字符

android - 如何通过本地网络中的主机名查找IP地址?

c++ - 如何处理在方法中间在内存中移动的对象?

python - 如何在python中为接口(interface)分配IP地址?

python - 带有值检查的生成器表达式

bash - 从 bash shell 脚本连接到 mongoDB

java - 关于垃圾收集内部的一些问题?