Python 多进程 Numpy 随机数

5 投票
2 回答
3686 浏览
提问于 2025-04-17 13:32

在使用Python的multiprocessing模块时,调用一个函数的作用范围是否有所不同?下面是一个例子:

我用multiprocessing模块调用一个函数,代码是这样的:

for core in range(cores):
    #target could be f() or g()
    proc = mp.Process(target=f, args=(core))
    jobs.append(proc)
for job in jobs:
    job.start()
for job in jobs:
    job.join()

def f(core):
    x = 0
    x += random.randint(0,10)
    print x

def g(core):
    #Assume an array with 4 columns and n rows
    local = np.copy(globalshared_array[:,core])
    shuffled = np.random.permutation(local)

当我调用f(core)时,x这个变量是这个进程内部的,也就是说,它会打印出一个不同的、随机的整数,正如我预期的那样。这些整数的值都不会超过10,这表明在每个进程中x=0。这样理解对吗?

接着我调用g(core),并对数组的一个副本进行打乱,结果返回了4个完全相同的“打乱”数组。这似乎表明,工作副本并不是在子进程内部的。这样理解对吗?如果是这样的话,除了使用共享内存之外,是否有可能让一个ndarray在子进程内部是本地的,而又需要从共享内存中填充数据呢?

编辑:

我修改了g(core),添加了一个随机整数,似乎达到了预期效果。数组显示出不同的值。看起来在permutation中发生了某种情况,导致每个子进程的列被随机排序成相同的样子……有什么想法吗?

def g(core):
    #Assume an array with 4 columns and n rows
    local = np.copy(globalshared_array[:,core])
    local += random.randint(0,10)

编辑 II:

np.random.shuffle也表现出相同的行为。数组的内容在打乱,但每个核心打乱后的值却是相同的。

2 个回答

4

要生成一个随机数组,这篇帖子提供了很有用的信息。下面的 g(core) 函数成功地为每个核心生成了一个随机排列。

def g(core):
    pid = mp.current_process()._identity[0]
    randst = np.random.mtrand.RandomState(pid)
    randarray = randst.randint(0,100, size=(1,100)
5

调用 g(core) 并对数组的一个副本进行重新排列,会返回 4 个完全相同的“打乱”数组。这似乎表明,工作副本在子进程中并不是局部的。

这很可能意味着每个子进程中的随机数生成器都是以相同的方式初始化的,因此产生了相同的序列。你需要给每个子进程的生成器设置一个种子(可以把子进程的 ID 加进去)。

撰写回答