gpt4 book ai didi

python - ThreadPoolExecutor、ProcessPoolExecutor 和全局变量

转载 作者:行者123 更新时间:2023-12-03 16:40:40 45 4
gpt4 key购买 nike

我是一般并行化的新手,特别是 concurrent.futures。我想对我的脚本进行基准测试并比较使用线程和进程之间的差异,但我发现我什至无法运行它,因为在使用 ProcessPoolExecutor 时我不能使用我的全局变量。

以下代码将输出 Hello正如我所料,但是当您更改时 ThreadPoolExecutorProcessPoolExecutor ,它将输出 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参数的,而且有很多。因此,似乎不建议将它们作为参数传递。那么如何将这些全局变量正确地传递给每个进程/线程呢?

我知道我可以改变周围的东西,这会起作用,但我不明白为什么。例如。以下对两个 Executor 都适用,但这也意味着必须对每个实例进行全局初始化。
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 上的行为可能不同,我必须注意我在 Windows 10 64 位上运行 Python 3.6。)

最佳答案

我不确定这种方法的局限性,但您可以在主进程/线程之间传递(可序列化?)对象。这也将帮助您摆脱对全局变量的依赖:

from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor

def process(opts):
opts["process"] = "got here"
print("In process():", opts)

return None


def main(opts):
opts["main"] = "got here"
executor = [ProcessPoolExecutor, ThreadPoolExecutor][1]
with executor(max_workers=1) as executor:
executor.submit(process, opts)

return None


def init(opts): # Gather CLI opts and populate dict
opts["init"] = "got here"

return None


if __name__ == '__main__':
cli_opts = {"__main__": "got here"} # Initialize dict
init(cli_opts) # Populate dict
main(cli_opts) # Use dict

适用于两种执行器类型。

编辑:尽管听起来这对您的用例来说不会成为问题,但我会通过 ProcessPoolExecutor 指出这一点。 , opts dict 你进去 process将是一个卡住的副本,因此它的突变将不会跨进程可见,也不会在您返回 __main__ 后可见。堵塞。 ThreadPoolExecutor ,另一方面,将在线程之间共享 dict 对象。

关于python - ThreadPoolExecutor、ProcessPoolExecutor 和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50872180/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com