python - 在 Multiprocessing python 中无法访问全局变量

标签 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给出的答案为我解决了这个问题,但有人可以解释为什么我们需要在 multiprocessing 的情况下传递 globals 而在正常执行的情况下为什么不需要传递?

最佳答案

当我添加 globals() 时它起作用了作为 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 import 以某种方式超出函数范围 x (如果我将 import os 移动到 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>

关于python - 在 Multiprocessing python 中无法访问全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55024907/

相关文章:

python - 以大型 numpy 数组作为参数的多处理

python - 在按下的每个键上实现自动建议

python - 通过鼠标单击更新 tkinter 标签

python - 将 request.user 与 Django ModelForm 一起使用

python 3.4 多处理不适用于 unittest

python - multiprocessing pool.map() 得到 "TypeError: list indices must be integers, not str"

python - 重新引发异常有什么意义?

python - 如何阻止 Django 转义 # 符号

python - PyQt 中程序退出后不会关闭

python - 当参数包含队列时,如何将特定于工作程序的初始化参数传递给工作程序池?