gpt4 book ai didi

python - 衍生进程中的操作系统环境变量读取

转载 作者:行者123 更新时间:2023-11-28 17:04:21 25 4
gpt4 key购买 nike

这类似于 a previous question但对于 multiprocessing 而不是 subprocess。似乎动态更改 PYTHONHASHSEED 在使用 multiprocessing 时没有效果,这与 subprocess 不同:

#check_environ.py
import os, multiprocessing, subprocess, sys

s = 'hello'
print('parent', os.getenv('PYTHONHASHSEED'), hash(s))

if len(sys.argv) > 1:
os.environ['PYTHONHASHSEED'] = sys.argv[1]
subprocess.call(['python', '-c', "import os;print('subprocess', os.getenv('PYTHONHASHSEED'), hash('{}'))".format(s)])
multiprocessing.Process(target=lambda:print('multiprocessing', os.getenv('PYTHONHASHSEED'), hash(s))).start()

样本运行:

# explicit PYTHONHASHSEED for subprocess/multiprocessing 
$ python check_environ.py 12

parent None 4472558296122225349
subprocess 12 -8207222429063474615
multiprocessing 12 4472558296122225349

# random PYTHONHASHSEED for subprocess/multiprocessing
$ python check_environ.py

parent None 7990499464460966677
subprocess None 1081030409066486350
multiprocessing None 7990499464460966677

所以无论如何,multiprocessing 哈希使用与父级相同的种子。有没有办法强制 multiprocessing 生成的子进程使用不同的哈希种子?

最佳答案

您可以使用除“fork”之外的另一种启动方法来创建进程。您的操作系统正在使用 fork(您不会因为使用 lambda 作为目标而得到 PicklingError)。

您可以使用 multiprocessing.set_start_method('spawn') 将启动方法更改为“spawn”(Windows 上的默认且唯一选项)或更改为“forkserver”(如果可用)。使用 multiprocessing.get_all_start_methods() 获取所有可用方法。

#check_environ.py
import sys, os, subprocess
import multiprocessing as mp


def show(s):
print('multiprocessing', os.getenv('PYTHONHASHSEED'), hash(s))


if __name__ == '__main__':

mp.set_start_method('spawn')

s = 'hello'
print('parent', os.getenv('PYTHONHASHSEED'), hash(s))

if len(sys.argv) > 1:
os.environ['PYTHONHASHSEED'] = sys.argv[1]

cmd = "import os; " \
"print('subprocess', os.getenv('PYTHONHASHSEED'), hash('{}'))"
subprocess.call(['python', '-c', cmd.format(s)])
p = mp.Process(target=show, args=(s,))
p.start()
p.join()

终端输出:

$ python check_environ.py 12

parent None 4279361553958749032
subprocess 12 -8207222429063474615
multiprocessing 12 -8207222429063474615

如果您需要多次在启动方法之间切换,请使用上下文对象来设置启动方法:

ctx = mp.get_context('spawn')
p = ctx.Process(target=foo, args=(var,))

但是要准备好为使用不同于 fork 的另一种启动方法付出大量的时间代价。我对运行 Ubuntu 18.04 的机器上的 python 进程进行了基准测试:

  • fork 1.59 毫秒
  • forkserver 289.83 毫秒
  • 产生 348.20 毫秒

但这不一定与您的用例相关。

关于python - 衍生进程中的操作系统环境变量读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52044045/

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