当前位置: 首页 > 面试题库 >

如何与子进程共享父进程的numpy随机状态?

利永年
2023-03-14
问题内容

我在程序开始时设置了numpy随机种子。在程序执行期间,我使用多次运行一个函数multiprocessing.Process。该函数使用numpy随机函数绘制随机数。问题是Process获取当前环境的副本。因此,每个进程都独立运行,并且都以与父环境相同的随机种子开始。

所以我的问题是如何在父环境中与子进程环境共享numpy的随机状态?请注意,我想Process用于自己的工作,需要使用一个 单独的类
import numpy在该类中单独进行操作。我尝试使用multiprocessing.Manager来共享随机状态,但是似乎事情没有按预期进行,并且我总是得到相同的结果。同样,将for循环移入内部drawNumpySamples还是保留在循环中都没有关系main.py。我仍然无法获得不同的数字,并且随机状态始终相同。这是我的代码的简化版本:

# randomClass.py
import numpy as np
class myClass(self):
    def __init__(self, randomSt):
        print ('setup the object')
        np.random.set_state(randomSt)
    def drawNumpySamples(self, idx)
        np.random.uniform()

并在主文件中:

    # main.py
    import numpy as np
    from multiprocessing import Process, Manager
    from randomClass import myClass

    np.random.seed(1) # set random seed
    mng = Manager()
    randomState = mng.list(np.random.get_state())
    myC = myClass(randomSt = randomState)

    for i in range(10):
        myC.drawNumpySamples() # this will always return the same results

注意 :我使用Python
3.5。我还在Numpy的GitHub页面上发布了一个问题。只需在此处发送问题链接以供将来参考。


问题答案:

即使您设法做到这一点,我也不认为它会做您想要的。一旦有多个进程并行地从同一个随机状态中拉出,就不再确定它们各自到达状态的顺序,这意味着您的运行实际上不会重复。可能有一些解决方法,但这似乎是一个不小的问题。

同时,有一个解决方案应同时解决您想要的问题和不确定性问题:

在生成子进程之前,请向RNG询问随机数,并将其传递给子进程。然后,孩子可以用该数字播种。然后,每个子代将具有与其他子代不同的随机序列,但是如果您使用固定种子重新运行整个应用程序,则每个子代将具有与同一子代相同的随机序列。

如果您的主流程执行了可能不确定地依赖于子流程执行的任何其他RNG工作,那么您将需要在提取任何其他随机数之前按顺序为所有子流程预先生成种子。

正如senderle在评论中指出的那样:如果您不需要多次不同的运行,而只需要进行一次固定运行,则甚至不需要从已播种的RNG中提取种子。只需使用一个从1开始的计数器,并为每个新进程递增它,并将其用作种子即可。我不知道这是否可以接受,但是如果可以接受,很难比这更简单。

正如Amir在评论中指出的那样:一种更好的方法是每次生成新进程时都绘制一个随机整数,并将该随机整数传递给新进程,以使用该整数设置numpy的随机种子。这个整数确实可以来自np.random.randint()



 类似资料:
  • 我尝试使用C语言中的< code>fork()函数处理Linux中的多个进程,这是我的代码: 现在让我们假设父进程ID为100,两个子进程(p1, p2)ID为101 相反,我看到了一些不同的东西,两个子进程具有相同的PPID,但第一个进程具有与之不同的PID。这是我得到的示例输出: 我的问题是,两个子进程的父PID不应该是3383吗?希望有人能解释这一切在这里是如何运作的,以及我做错了什么(或想

  • 问题内容: 是否可以从Shell脚本中的父进程ID获取子进程ID? 我有一个要使用Shell脚本执行的文件,这会导致一个新进程 process1 (父进程)。这个 过程1 已经分叉的另一个进程 过程2 (子进程)。使用脚本,我可以使用以下命令获取 process1 的pid : 但我无法获取子进程的pid。 问题答案: 只需使用:

  • 是否可以从外壳脚本中的父进程ID获取子进程ID? 我有一个要使用shell脚本执行的文件,这会导致一个新的进程process1(父进程)。此进程1已经派生了另一个进程process2(子进程)。使用脚本,我可以使用以下命令获得进程1的pid: 但是我无法获取子进程的pid。

  • 用例 我有一个基于gRPC Guice的服务应用程序,其中对于特定的调用,代码流如下所示:

  • 问题内容: 假设我有一个进程,它恰好产生了一个子进程。现在,当父进程出于某种原因(正常或异常,通过kill,^ C,断言失败或其他任何原因)退出时,我希望子进程死亡。如何正确地做到这一点? 问题答案: 子进程可以通过在syscall中指定选项来要求父进程去世时内核发出(或其他信号),如下所示: 有关详细信息,请参见。 编辑:这是仅Linux

  • 问题内容: 我想使用模块来完成此操作。 当我这样做时,例如: 我启动一个父进程,然后让父进程产生一个子进程, 然后我希望父进程退出自身,但子进程继续工作。 请允许我写一个 错误 代码来解释一下自己: 那么,我如何启动一个在父进程完成时不会被杀死的进程? 20140714 大家好 我的朋友刚刚告诉我一个解决方案… 我只是想… 无论如何,只要让您看到: 这确实有效!! 问题答案: 一个技巧:调用以退出