gsa*_*kis 5 python multiprocessing python-multiprocessing
这与之前的问题类似,但 formultiprocessing而不是subprocess。与 不同的是,使用 时动态更改似乎PYTHONHASHSEED没有效果:multiprocessingsubprocess
#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()
Run Code Online (Sandbox Code Playgroud)
样本运行:
# 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
Run Code Online (Sandbox Code Playgroud)
因此,无论如何,multiprocessing哈希值都使用与父级相同的种子。有没有办法强制使用multiprocessing不同的哈希种子生成子进程?
您可以使用“fork”之外的另一种启动方法来创建进程。你的操作系统正在使用 fork (你不会PicklingError因为使用 lambda 作为目标而得到 a )。
您可以使用 或 'forkserver'(如果可用)将启动方法更改为“spawn”(Windows 上的默认且唯一选项)multiprocessing.set_start_method('spawn')。获取所有可用的方法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()
Run Code Online (Sandbox Code Playgroud)
终端输出:
$ python check_environ.py 12
parent None 4279361553958749032
subprocess 12 -8207222429063474615
multiprocessing 12 -8207222429063474615
Run Code Online (Sandbox Code Playgroud)
如果需要多次在启动方法之间切换,请使用上下文对象来设置启动方法:
ctx = mp.get_context('spawn')
p = ctx.Process(target=foo, args=(var,))
Run Code Online (Sandbox Code Playgroud)
但要准备好为使用除 fork 之外的另一种启动方法而付出大量的时间损失。我在运行 Ubuntu 18.04 的机器上刚刚启动一个 python 进程进行了基准测试:
但这不一定与您的用例相关。
| 归档时间: |
|
| 查看次数: |
2546 次 |
| 最近记录: |