簡體   English   中英

全局變量在Multiprocessing python中不可訪問

[英]globals are not accessible inside the Multiprocessing python

我的應用程序需要執行一些任意的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

當我將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報告name 'os' is not defined的原因是因為以某種方式將os導入置於函數x的范圍之外(如果我將import os移到x函數中,則您的代碼將真正起作用)所以我決定添加globals()作為參數,以便exec()可以將os導入添加到globals()並在x函數由eval()調用時進行訪問。

如果在exec (source, globals()) globals()之前和之后打印出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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM