在python中设置随机种子会干扰多进程

2024-06-02 07:54:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我观察到在python中使用多处理之前设置一个随机种子会导致奇怪的行为。在

在python3.5.2中,只有2个或3个内核使用的CPU使用率很低。 在Python2.7.13中,所有请求的内核都以100%的速度使用,但是代码似乎永远都没有完成。当我删除随机种子的初始化时,并行化工作得很好。在

即使在并行化函数中没有显式使用random,也会发生这种情况。我现在假设种子是在进程之间共享的,这会妨碍多进程的顺利运行,但是有人能给出正确的答案吗?在


我在Linux上运行了代码,下面是一个最小的代码示例:

from multiprocessing import Pool
import numpy as np
import random

random.seed = 2018

NB_CPUS = 4

def test(x):
    return x**2

pool = Pool(NB_CPUS)
args = [np.random.rand() for _ in range(100000)]

results = pool.map(test, args)

pool.terminate()
results[-5:]

Tags: 代码testimport进程npargsrandomcpu
1条回答
网友
1楼 · 发布于 2024-06-02 07:54:44

回答有点晚了,但是您将^{} function设置为int,这是在破坏事情。你应该做的是:

random.seed(2018)

回溯的最后几行提供了应该使这一点显而易见的背景:

^{pr2}$

这会导致Pool继续尝试创建新的工作进程,但因为每次无法向前推进时都会发生这种情况。在

这背后是multiprocessing知道它应该在分叉时重新设定随机模块的种子,这样子进程就不会共享相同的RNG状态。为此,它尝试调用random.seed函数,但您已将其设置为不可调用的int,因此出现错误!在

与此相关的另一个问题是multiprocessing不知道重新为NumPy RNG种子,因此下面的代码:

from multiprocessing import Pool
import numpy as np

def test(i):
    print(i, np.random.rand())

with Pool(4) as pool:
    pool.map(test, range(4))

将导致每个工人打印相同的值。This issue已经知道一段时间了,但是仍然是开放的。您可以通过使用worker initializer来解决此问题,例如:

def initfn():
    np.random.seed()

with Pool(4, initializer=initfn) as pool:
    pool.map(test, range(4))

现在将导致上面的test函数打印不同的值。请注意,如果不进行任何其他工作级初始化,您甚至可以使用Pool(4, initializer=np.random.seed)。在

相关问题 更多 >