python教程—Python多处理。池懒惰的迭代-Python实用宝典

python教程—Python多处理。池懒惰的迭代

我想知道python的多处理方式。池类使用map、imap和map_async。我的特殊问题是,我想要映射到一个创建内存重对象的迭代器上,而不希望所有这些对象都同时生成到内存中。我想看看各种map()函数是否会榨干我的迭代器,或者只在子进程进展缓慢时智能地调用next()函数,所以我对一些测试进行了修改,如下所示:

我想知道python的多处理方式。池类使用map、imap和map_async。我的特殊问题是,我想要映射到一个创建内存重对象的迭代器上,而不希望所有这些对象都同时生成到内存中。我想看看各种map()函数是否会榨干我的迭代器,或者只在子进程进展缓慢时智能地调用next()函数,所以我对一些测试进行了修改,如下所示:

    def g(): for el in xrange(100): print el yield el def f(x): time.sleep(1) return x*x if __name__ == '__main__': pool = Pool(processes=4) # start 4 worker processes go = g() g2 = pool.imap(f, go) g2.next()

map imap map_async也是如此。然而,这是最明显的例子,因为仅仅在g2上调用next()一次就可以打印出生成器g()中的所有元素,而如果imap是“惰性地”执行此操作,那么我希望它只调用go.next()一次,因此只打印出“1”。

有人能清楚发生了什么吗?是否有某种方法可以让流程池根据需要“惰性地”评估迭代器?

谢谢,

加布

回答

让我们先看看程序的结尾。

多处理模块使用atexit调用multiprocessing.util。当你的程序结束时。

如果删除g2.next(),程序将很快结束。

_exit_function最终调用Pool._terminate_pool。主线程更改pool._task_handler的状态。_state from RUN to TERMINATE。与此同时,池。_task_handler线程在池中循环。_handle_tasks,当它到达条件时退出

    if thread._state: debug('task handler found thread._state != RUN') break

(见/usr/lib/python2.6/multiprocessing / pool.py)

这就是阻止任务处理程序完全使用生成器g()的原因。如果你在游泳池里看。_handle_tasks你会看到

    for i, task in enumerate(taskseq): ... try: put(task) except IOError: debug('could not put task on queue') break

这是使用生成器的代码。(taskseq并不完全是您的生成器,但是随着taskseq的使用,您的生成器也在使用。)

相反,当您调用g2.next()时,主线程调用IMapIterator。然后,当它到达self._con .wait(超时)时等待。

主线程在等待而不是
调用_exit_function使任务处理程序线程能够正常运行,这意味着当生成器将任务放入池中的worker的inqueue中时,它将完全消耗生成器。_handle_tasks函数。

底线是,所有池映射函数都使用给定的整个迭代器。如果你想把生成器分成块使用,你可以这样做:

    import multiprocessing as mp import itertools import time def g(): for el in xrange(50): print el yield el def f(x): time.sleep(1) return x * x if __name__ == '__main__': pool = mp.Pool(processes=4) # start 4 worker processes go = g() result = [] N = 11 while True: g2 = pool.map(f, itertools.islice(go, N)) if g2: result.extend(g2) time.sleep(1) else: break print(result)

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
0

发表评论