与多处理模块一起使用的全局变量的异常行为

时间:2019-05-05 17:37:54

标签: python-3.x multiprocessing global-variables

我正在重写我的应用程序。虽然我想使用全局变量将一些信息传递给函数。我注意到全局变量的值在更改后没有更改。此外,我注意到,行为会因“ pool.map_async”的语法而异。下面是重现此错误的代码。

第一个示例是,当作业没有任何参数,但是我像这样的“ func = job()”将“ job()”传递给“ = func”(仅传递“ job”看起来像一个进程正在执行)

from multiprocessing import Pool

x = None

def job():
    print(x,"Inside Job")

def main():
    global x
    x = 10
    pool = Pool(1)
    li = [0]
    pool.map_async(iterable=li,func=job())
    pool.close()
    pool.join()
    print("End of main")

if __name__ == "__main__":
    print(x,"Before")
    main()
    print(x,"After")

控制台输出

None Before
10 Inside Job
End of main
10 After

输出符合预期,作业内部的值x正确。

现在,如果让函数job接受如下所示的任何参数

from multiprocessing import Pool

x = None

def job(z):
    print(z)
    print(x,"Inside Job")

def main():
    global x
    x = 10
    pool = Pool(1)
    li = [0]
    pool.map_async(iterable=li,func=job)
    pool.close()
    pool.join()
    print("End of main")

if __name__ == "__main__":
    print(x,"Before")
    main()
    print(x,"After")

控制台输出

None Before
0
None Inside Job
End of main
10 After

输出显示未注意到更改x的值。

有人可以解释为什么函数“ job”带有参数时为什么不能使用“ global”吗?

我在python 3.7.0上

1 个答案:

答案 0 :(得分:1)

您的第一个示例就是“错”。 job函数必须接受一个参数。

在该示例中,这里是往南走的地方:

    pool.map_async(iterable=li, func=job())

您想要:

    pool.map_async(iterable=li, func=job)

相反。

函数的返回值为None, 因此,您需要在job()的上下文中同步执行main, 然后将结果None传递给map_asyncglobal中的main语句影响了x的查找。

第二个例子看起来更好。它会正确显示0

与其尝试使用global存储值,不如 如果将这样的值存储在对象中,您会更快乐 并将对象作为参数传递给job。例如:

class Point:

    def __init__(self, x, y):
        self.x = x
        self.y = y

points = [Point(3, 4), Point(5, 6)]
pool.map_async(iterable=points, func=job)

多处理文档指向map()文档。 加上只能提供一个可迭代的事实, 他们的建议可以归结为:

  

功能必须带有[one]参数