子进程与父进程生成相同“随机”数问题求助
解决concurrent.futures多进程下numpy随机数重复的问题
看起来你碰到了多进程下numpy随机数重复的经典问题——我来帮你拆解原因和解决办法:
问题原因
当你用ProcessPoolExecutor启动多进程时,所有子进程都会复制主进程的numpy随机状态。这意味着每个子进程一开始都拥有完全相同的随机种子,所以生成的随机序列自然完全一致,就出现了你看到的重复输出。
解决方案
这里有两种可靠的解决思路,你可以根据需求选择:
1. 在子进程中独立初始化随机生成器
最直接的方式是让每个子进程启动后重新初始化随机状态,避免和主进程以及其他子进程共享:
import numpy as np from concurrent.futures import ProcessPoolExecutor, as_completed from time import sleep def calc_g(): sleep(1) # 重置随机种子(基于系统时间/进程ID自动生成) np.random.seed() u = np.random.uniform() print(u) futures = {} with ProcessPoolExecutor() as executor: for i in range(0,10): job = executor.submit(calc_g) futures[job] = i for job in as_completed(futures): job.result()
更推荐的是创建独立的RandomState实例,这样能避免全局状态的干扰:
def calc_g(): sleep(1) # 创建独立的随机生成器 rng = np.random.RandomState() u = rng.uniform() print(u)
2. 主进程分配唯一种子(适合需要可复现的场景)
如果需要模拟结果可复现,可以在主进程中为每个子进程生成唯一的随机种子,传递给子进程使用:
def calc_g(seed): sleep(1) rng = np.random.RandomState(seed) u = rng.uniform() print(u) futures = {} with ProcessPoolExecutor() as executor: for i in range(0,10): # 主进程生成唯一种子 seed = np.random.randint(0, 10**6) job = executor.submit(calc_g, seed) futures[job] = i
验证效果
修改后的代码运行时,每个进程都会输出不同的随机数,不会再出现重复的情况。
内容的提问来源于stack exchange,提问作者Leo Ribeiro
相关产品推荐
相关产品推荐

