multiprocessing.pool.MapResult._number_left没有给出结果我期望

时间:2018-04-12 23:44:23

标签: python multiprocessing pool

我对_number_left应该返回的内容感到困惑。我假设它是池中剩余的数字任务,但它似乎没有在我的代码中提供正确的值。例如,如果我有一个10名工人的池数到1000,我希望result._number_left从1000开始倒计时。但是,它只告诉我在代码完成之前我剩下40个。我在这里错过了什么吗?

代码:

import multiprocessing
import time


def do_something(x):
    print x
    time.sleep(1)
    return


def main():
    pool = multiprocessing.Pool(10)

    result = pool.map_async(do_something, [x for x in range(1000)])
    while not result.ready():
        print("num left: {}".format(result._number_left))
        result.wait(timeout=1)


if __name__ == "__main__":
    main()

2 个答案:

答案 0 :(得分:1)

首先,_number_left是未记录的类的未记录的私有属性。您没有理由期望它具有任何特定含义。

如果你看一下the source for the undocumented MapResult课程,你可以看到它在CPython 3.6中的使用方式。

首先,它被初始化:

self._number_left = length//chunksize + bool(length % chunksize)

所以,很明显,它永远不会是你的迭代的长度;这将是映射整个迭代所需的块的预期数量。然后,每当调用_set时,它都会从那里倒计时,这......这很复杂,但显然不是每个值一次。

无论如何,无论你想做什么,都可能有办法实际做到这一点,而不是偷看私人属性并猜测它们可能意味着什么。例如,如果你只想获得一些进展,但不能使用imap_unordered因为你需要在最后的有序列表中得到结果,那么很容易从中构建一个有序列表:只需传递{ {1}} in,修改或包装enumerate(iterable)以返回索引和值,然后对返回的结果进行排序。

答案 1 :(得分:0)

原来我需要在chunksize=1电话中添加map_async。找到答案here

新守则:

import multiprocessing
import time


def do_something(x):
    print x
    time.sleep(1)
    return


def main():
    pool = multiprocessing.Pool(10)

    result = pool.map_async(do_something, [x for x in range(1000)], chunksize=1)
    while not result.ready():
        print("num left: {}".format(result._number_left))
        result.wait(timeout=1)


if __name__ == "__main__":
    main()