Windows中pool.map的属性错误

时间:2014-07-10 14:51:29

标签: python windows multiprocessing

所以我有这段代码:

def someFunction (S):
    pass

if __name__ == "__main__":

    import time
    start = time.time()

    G = nx.read_gpickle("../../graphs/graph.gpickle")

    Ep = dict()
    with open("Ep.txt") as f:
        for line in f:
            data = line.split()
            Ep[(int(data[0]), int(data[1]))] = float(data[2])

    pool = None
    def mapAvgSize (S):
        return avgIAC(G, S, Ep, I)
    if pool == None:
        pool = multiprocessing.Pool(processes=4)

    print 'Start Initialization...'
    S = []


    print 'Selecting S...'
    print 'before pool.map'
    Ts = pool.map(mapAvgSize, [S]*4)
    print 'after pool.map'

看起来一切正确:我在池之前定义了函数,将所有内容放在if __name__ == "__main__":语句下。但不幸的是,上面的代码上升到行print 'before pool.map',然后抛出一个错误:

AttributeError: 'module' object has no attribute 'mapAvgSize'

最奇怪的部分是上面的代码在Linux下工作,但在Windows上失败(我想在具有更多内核的计算机上在笔记本电脑之外进行测试)。

任何帮助,以了解代码在Windows上失败的原因将受到赞赏和upvoted。

1 个答案:

答案 0 :(得分:2)

如前所述,您需要使mapAvg成为顶级功能。因为它目前关闭了一些" local"变量,你也需要解决这个问题。您可以使用初始化程序(示例中为mapped + initializer)传递当前已关闭的变量,也可以将其传递给您可迭代的映射(mapped2

示例,演示(部分)您的选择:

import multiprocessing


globalB = None


def mapped(a):
    global globalB
    return a * globalB


def initializer(*args):
    global globalB
    globalB, = args


def mapped2(args):
    a, b = args
    return a * b


if __name__ == "__main__":
    myB = 2
    pool = multiprocessing.Pool(processes=5,
                                initializer=initializer,
                                initargs=(myB,)
                                )
    # Using the initializer provided globalB
    for i in pool.map(mapped, range(10)):
        print i

    # directly provided as an arg
    for i in pool.map(mapped2, ((a, myB) for a in range(10))):
        print i

在您的代码中,您当然可以将EpG(以及I}移动到顶级,但是您导致文件I / o每个池进程,所以如果我必须实现它,我应该使用mapped2(使用专用的队列项而不是某些元组)。

PS:这甚至可以在Linux上运行的原因(有时候?!)似乎是fork()工作原理的偶然结果。你不应该依赖它。