Python 多处理、池和随机性

Python 多处理、池和随机性,python,random,python-multiprocessing,Python,Random,Python Multiprocessing,我正在经历一件奇怪的事情:我写了一个模拟经济的程序。我不想在一个CPU核上一个接一个地运行这个模拟,而是想使用多处理来加快速度。所以我运行我的代码(很好),我想从我正在进行的模拟中获得一些统计数据。然后出现了一个惊喜:所有在同一时间进行的模拟产生了非常相同的结果!Pool()和random.seed()之间是否存在某种奇怪的关系 更清楚地说,以下代码可以概括为: class Economy(object): def __init__(self,i): self.run_n

我正在经历一件奇怪的事情:我写了一个模拟经济的程序。我不想在一个CPU核上一个接一个地运行这个模拟,而是想使用多处理来加快速度。所以我运行我的代码(很好),我想从我正在进行的模拟中获得一些统计数据。然后出现了一个惊喜:所有在同一时间进行的模拟产生了非常相同的结果!Pool()和random.seed()之间是否存在某种奇怪的关系

更清楚地说,以下代码可以概括为:

class Economy(object):
    def __init__(self,i):
        self.run_number = i
        self.Statistics = Statistics()
        self.process()

def run_and_return(i):
    eco = Economy(i)
    return eco

collection = []
def get_result(x):
    collection.append(x)

if __name__ == '__main__':
    pool = Pool(processes=4)
    for i in range(NRUN):
        pool.apply_async(run_and_return, (i,), callback=get_result)
    pool.close()
    pool.join()
过程(i)是在i个步骤中通过模拟的每个步骤的函数。基本上我模拟了NRUN经济体,从中我得到了我放在列表集合中的统计数据

奇怪的是,前4次运行的结果完全相同:在相同的模拟“波”中,我得到了非常相同的结果。一旦我到达第二波,接下来的4次模拟将得到不同的输出

如果我使用进程=1的同一个程序,所有这些模拟都运行得很好:当我只在一个内核上工作时,会得到不同的结果,一个接一个地进行模拟。。。我已经尝试了一些事情,但无法让我的头脑围绕这一点,因此我的帖子

非常感谢您花时间阅读这篇长篇文章,请不要犹豫要求更多的精确性


最好的是,

如果您在Linux上,那么每个池进程都是通过分叉父进程来完成的。这意味着这个过程实际上是重复的——这包括任何随机对象可能使用的种子

随机模块在导入时为其默认函数选择种子。这意味着在创建池之前已选择种子

要解决这个问题,必须为每个池进程使用一个初始化器,该初始化器将随机种子设置为唯一的

使用进程id和当前时间作为种子
random
是一种不错的方法。在程序的一次运行中,进程id必须是唯一的。同时,如果生成相同的流程id,则使用时间将确保多次运行的唯一性。将进程id和时间作为字符串传递意味着该字符串的摘要也用于为随机数生成器播种,这意味着两个相似的字符串将产生实质上不同的种子。或者,您可以使用
uuid
模块生成种子

def proc_init():
    random.seed(str(os.getpid()) + str(time.time()))

pool = Pool(num_procs, initializer=proc_init)

你在哪里使用随机的?是的,Reut,我在process()函数中使用了很多随机的,这就是为什么我没有详细介绍的原因。。。谢谢Oleh,我来看看文档!这仍然是最奇怪的事情,因为目标函数有不同的输入。。。非常感谢。可能就是这样,我在Linux上!所以现在我只需要检查如何为每个进程设置一个特定的随机种子。。。谢谢谢谢你的精确性。。。但这仍然是最奇怪的事情:我确实为池中的每个工人获得了不同的种子,但相同的“波”num_procs的经济产出在整个过程中仍然是相同的。。。当种子不在的时候!我很确定它不是来自我的代码,因为如果我用num_procs=1运行它,我会得到不同的结果。。。很奇怪!我不同意。在我看来,每一次经济运行都会导致某种初始状态的变异。有一个假设,即经济将按顺序运行,以便所有以不同状态开始的运行。相反,开始状态被复制到所有工作进程。它们都是在相同的状态下启动的,因此它们都产生相同的输出。如果不知道统计和经济的本质,我就说不出这种重复的状态是从哪里来的(如果不是来自随机的话)。你说得对,先生!我不仅使用了random,还使用了numpy.random,其行为方式与。。。因此,每个员工库都有相同的numpy种子,这就解释了为什么!非常感谢你!最好的方法是,使用不带参数的MaxUsing
random.seed()
应该将
os.uradom
作为seed的源。这应该比时间和PID更好。