python - 多处理 Pool.imap 坏了?

标签 python multiprocessing

我已经尝试了 python2.6 Ubuntu 中包含的多处理 包(__version__ 表示 0.70a1)和来自 PyPI (2.6.2.1) 的最新版本。 在这两种情况下,我都不知道如何正确使用 imap - 它会导致 整个解释器停止响应 ctrl-C(虽然 map 工作正常)。 pdb 显示 next() 卡在 IMapIterator 中的条件变量 wait() 调用上,因此没有人唤醒我们。有什么提示吗?谢谢 提前。

$ cat /tmp/go3.py
import multiprocessing as mp
print mp.Pool(1).map(abs, range(3))
print list(mp.Pool(1).imap(abs, range(3)))

$ python /tmp/go3.py
[0, 1, 2]
^C^C^C^C^C^\Quit

最佳答案

首先请注意这是可行的:

import multiprocessing as mp
import multiprocessing.util as util
pool=mp.Pool(1)
print list(pool.imap(abs, range(3)))

不同之处在于 pool 在调用 pool.imap() 结束时不会完成。

相比之下,

print(list(mp.Pool(1).imap(abs, range(3))))

导致 Pool 实例在 imap 调用结束后很快完成。 缺少引用会导致调用 Finalizer(在 Pool 类中称为 self._terminate)。这会启动一系列命令,这些命令会拆除任务处理程序线程、结果处理程序线程、工作子进程等。

这一切发生得如此之快,以至于至少在大多数运行中,发送到任务处理程序的任务没有完成。

下面是相关的代码:

来自/usr/lib/python2.6/multiprocessing/pool.py:

class Pool(object):
    def __init__(self, processes=None, initializer=None, initargs=()):
        ...
        self._terminate = Finalize(
            self, self._terminate_pool,
            args=(self._taskqueue, self._inqueue, self._outqueue, self._pool,
                  self._task_handler, self._result_handler, self._cache),
            exitpriority=15
            )

/usr/lib/python2.6/multiprocessing/util.py:

class Finalize(object):
    '''
    Class which supports object finalization using weakrefs
    '''
    def __init__(self, obj, callback, args=(), kwargs=None, exitpriority=None):
        ...
        if obj is not None:
            self._weakref = weakref.ref(obj, self)   

obj 即将完成时,weakref.ref(obj,self) 导致调用 self()

我使用调试命令 util.log_to_stderr(util.SUBDEBUG) 来了解事件的顺序。例如:

import multiprocessing as mp
import multiprocessing.util as util
util.log_to_stderr(util.SUBDEBUG)

print(list(mp.Pool(1).imap(abs, range(3))))

产量

[DEBUG/MainProcess] created semlock with handle 3077013504
[DEBUG/MainProcess] created semlock with handle 3077009408
[DEBUG/MainProcess] created semlock with handle 3077005312
[DEBUG/MainProcess] created semlock with handle 3077001216
[INFO/PoolWorker-1] child process calling self.run()
[SUBDEBUG/MainProcess] finalizer calling <bound method type._terminate_pool of <class 'multiprocessing.pool.Pool'>> with args (<Queue.Queue instance at 0x9d6e62c>, <multiprocessing.queues.SimpleQueue object at 0x9cf04cc>, <multiprocessing.queues.SimpleQueue object at 0x9d6e40c>, [<Process(PoolWorker-1, started daemon)>], <Thread(Thread-1, started daemon -1217967248)>, <Thread(Thread-2, started daemon -1226359952)>, {0: <multiprocessing.pool.IMapIterator object at 0x9d6eaec>}) and kwargs {}
[DEBUG/MainProcess] finalizing pool
...

比较
import multiprocessing as mp
import multiprocessing.util as util
util.log_to_stderr(util.SUBDEBUG)
pool=mp.Pool(1)
print list(pool.imap(abs, range(3)))

产生

[DEBUG/MainProcess] created semlock with handle 3078684672
[DEBUG/MainProcess] created semlock with handle 3078680576
[DEBUG/MainProcess] created semlock with handle 3078676480
[DEBUG/MainProcess] created semlock with handle 3078672384
[INFO/PoolWorker-1] child process calling self.run()
[DEBUG/MainProcess] doing set_length()
[0, 1, 2]
[INFO/MainProcess] process shutting down
[DEBUG/MainProcess] running all "atexit" finalizers with priority >= 0
[SUBDEBUG/MainProcess] calling <Finalize object, callback=_terminate_pool, args=(<Queue.Queue instance at 0xb763e60c>, <multiprocessing.queues.SimpleQueue object at 0xb76c94ac>, <multiprocessing.queues.SimpleQueue object at 0xb763e3ec>, [<Process(PoolWorker-1, started daemon)>], <Thread(Thread-1, started daemon -1218274448)>, <Thread(Thread-2, started daemon -1226667152)>, {}), exitprority=15>
...
[DEBUG/MainProcess] finalizing pool

关于python - 多处理 Pool.imap 坏了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5481104/

相关文章:

python - 多处理:每个任务的进度条

python - 给定一个输入字符串,如何在 O(k logN + W) 时间内搜索所有变位词,其中 W 是输出大小,k 是字符串中的最大字符数?

python - 找到适合给定起点的一组点的最大圆(numpy)

python 两个变量 - 找出哪个最接近零

python - 使用角坐标收缩多边形

python - 如何在 OSX 上的单独进程中读取网络摄像头?

python - 使用 Python 的倒排索引系统

C 多处理/管道

python - 每当子进程在 Python 3 的多处理池中完成时打印更新行

从命令行运行时,在pycharm中运行的python脚本出现内存分配错误