我对并行化和concurrent.futures都很陌生。我想要测试我的脚本并比较使用线程和进程的差异,但是我发现当我使用ProcessPoolExecutor
时,我无法使用全局变量。
以下代码将会输出我期望的Hello
,但是当你把ThreadPoolExecutor
改为ProcessPoolExecutor
时,它将会输出None
。
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
greeting = None
def process():
print(greeting)
return None
def main():
with ThreadPoolExecutor(max_workers=1) as executor:
executor.submit(process)
return None
def init():
global greeting
greeting = 'Hello'
return None
if __name__ == '__main__':
init()
main()
我不明白为什么会这样。在我的实际程序中,init用于将全局变量设置为CLI参数,并且有很多这样的变量。因此,将它们作为参数传递似乎不是推荐的方法。那么我该如何正确地将这些全局变量传递给每个进程/线程呢?
我知道我可以改变代码,使其正常工作,但我不明白为什么。例如,以下代码对于执行器都有效,但这也意味着全局初始化必须发生在每个实例中。
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
greeting = None
def init():
global greeting
greeting = 'Hello'
return None
def main():
with ThreadPoolExecutor(max_workers=1) as executor:
executor.submit(process)
return None
def process():
init()
print(greeting)
return None
if __name__ == '__main__':
main()
所以我的主要问题是,到底发生了什么。为什么这段代码可以使用线程而不能使用进程?如何正确地将设置好的全局变量传递给每个进程/线程而不必为每个实例重新初始化它们?
(附注:因为我已经读到concurrent.futures在Windows上的行为可能会有所不同,所以我必须说明我正在运行Python 3.6,Windows 10 64位操作系统。)