全局变量在Multiprocessing python

时间:2019-03-06 14:01:06

标签: python multiprocessing

我的应用程序需要执行一些任意的python代码作为输入。 当我尝试使用Multiprocessing模块在不同的过程中执行它时,代码globals()会出现一些问题。

请考虑以下可正常工作的代码。

src = """import os
    def x():
        print(os.getcwd())"""

exec (src)
eval('x()')

此代码可以正常工作,没有任何错误。

当我想通过以下代码通过多处理执行同一件事时,它给我一个错误,即找不到os

from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=1)

src = """import os
def x():
    print(os.getcwd())"""

def my_eval(source):
    try:
        exec (source)
        eval('x()')
    except Exception as ex:
        print(ex)

pool.submit(my_eval, src)

在这种情况下的输出是

<Future at 0x7fcc4c160f28 state=running>
name 'os' is not defined

viethtran给出的答案为我解决了这个问题,但是有人可以解释为什么在globals的情况下我们需要通过multiprocessing在正常执行的情况下为什么不通过?

1 个答案:

答案 0 :(得分:0)

当我将exec()添加为from concurrent.futures import ProcessPoolExecutor pool = ProcessPoolExecutor(max_workers=1) src = """import os def x(): print(os.getcwd())""" def my_eval(source): try: exec (source, globals()) eval('x()') except Exception as ex: print(ex) pool.submit(my_eval, src) 函数的参数时,它可以工作。

name 'os' is not defined

更新: 我发现您的报告os的原因是x的导入在某种程度上超出了函数import os的范围(如果我移动{{1 }}放在x函数中),所以我决定添加globals()作为参数,以便exec()可以将os导入添加到globals()中并对其进行访问当x调用eval()函数时。

如果在globals()之前和之后打印exec (source, globals()),您会注意到模块os和函数x将被添加到globals()字典中。

from concurrent.futures import ProcessPoolExecutor
pool = ProcessPoolExecutor(max_workers=1)

src = """import os
def x():
    print(os.getcwd())"""

def my_eval(source):
    try:
        print('==========')
        print(globals())
        print('==========')
        exec(source, globals())
        print('++++++++++')
        print(globals())
        print('++++++++++')
        eval('x()')
    except Exception as ex:
        print(ex)

pool.submit(my_eval, src)

此代码将打印出如下内容:

==========
{'my_eval': <function my_eval at 0x7ff63c7baaa0>, 'ProcessPoolExecutor': <class 'concurrent.futures.process.ProcessPoolExecutor'>, 'src': 'import os\ndef x():\n    print(os.getcwd())', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, '__name__': '__main__', '__doc__': None, 'pool': <concurrent.futures.process.ProcessPoolExecutor object at 0x7ff640c14050>}
==========
++++++++++
{'my_eval': <function my_eval at 0x7ff63c7baaa0>, 'ProcessPoolExecutor': <class 'concurrent.futures.process.ProcessPoolExecutor'>, 'src': 'import os\ndef x():\n    print(os.getcwd())', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'test.py', '__package__': None, 'x': <function x at 0x7ff63c7bac80>, '__name__': '__main__', 'os': <module 'os' from '/home/viet/anaconda2/lib/python2.7/os.pyc'>, '__doc__': None, 'pool': <concurrent.futures.process.ProcessPoolExecutor object at 0x7ff640c14050>}
++++++++++
<your pwd here>