这与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
生成的子进程使用其他哈希种子?
答案 0 :(得分:1)
您可以通过使用除'fork'之外的其他启动方法来创建流程。您的操作系统正在使用fork(将lambda用作目标不会得到PicklingError
)。
您可以使用multiprocessing.set_start_method('spaw')
将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 :(得分:0)
每个python
进程都是在新操作系统环境中启动的,而在multiprocessing
情况下,只有一个被共享,并从父进程继承。