这与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
生成的子进程使用不同的散列种子? 最佳答案
您可以使用另一个start方法而不是“fork”来创建进程。您的操作系统正在使用fork(使用lambda作为目标不会得到PicklingError
)。
您可以使用multiprocessing.set_start_method('spawn')
将start方法更改为'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进程:
叉子1.59 ms
forkserver 289.83毫秒
产生348.20毫秒
但这不一定与您的用例相关。
关于python - 在生成的过程中读取OS环境变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52044045/