【问题标题】:Concurrent tasks deterministically generating pseudo random numbers并发任务确定性地生成伪随机数
【发布时间】:2018-11-10 18:36:59
【问题描述】:

我有一个返回伪随机字节列表的协程

import asyncio
import random
import os

async def random_bytes():
    random.seed(a=1234)
    results = []
    for _ in range(0, 128):
        await asyncio.sleep(int(os.urandom(1)[0])/4096)
        results.append(random.getrandbits(8))
    return results

loop = asyncio.get_event_loop()
task_1 = loop.create_task(random_bytes())
print(loop.run_until_complete(task_1))

正如预期的那样,这个列表在每次运行时总是相同的,即使每一代之间的时间间隔不同 [基于来自 os.urandom 的一些外部熵],伪随机数生成器的种子值相同.

现在,如果我同时运行其中两个,创建两个列表...

loop = asyncio.get_event_loop()
task_1 = loop.create_task(random_bytes())
task_2 = loop.create_task(random_bytes())
print(loop.run_until_complete(asyncio.gather(task_1, task_2)))

...列表总是不同的:任务基本上相互干扰,不再具有确定性。

如何生成两个并发的伪随机数任务,其中每个伪随机数列表都具有确定性,就好像没有其他任务正在运行一样?

[我的用例:测试并发行为,使用大量伪随机数,以非确定性间隔生成,但希望伪随机数本身对于每个任务的每次测试运行都是相同的]

【问题讨论】:

    标签: python python-3.x testing random python-asyncio


    【解决方案1】:

    来自random module docs

    此模块提供的函数实际上是 random.Random 类的隐藏实例的绑定方法。您可以实例化您自己的 Random 实例以获取不共享状态的生成器。

    async def random_bytes():
        generator = random.Random()
        generator.seed(1234)
        results = []
        for _ in range(0, 128):
            await asyncio.sleep(int(os.urandom(1)[0])/4096)
            results.append(generator.getrandbits(8))
        return results
    

    【讨论】:

      【解决方案2】:

      您可以使用random.getstaterandom.setstate,确保在设置状态、生成随机数和获取状态之间,您不要屈服于其他任务。

      async def random_bytes():
          random.seed(a=1234)
          state = random.getstate()
          results = []
          for _ in range(0, 128):
              await asyncio.sleep(int(os.urandom(1)[0])/4096)
              random.setstate(state)
              results.append(random.getrandbits(8))
              state = random.getstate()
          return results
      

      【讨论】:

        猜你喜欢
        • 2018-05-20
        • 1970-01-01
        • 1970-01-01
        • 2015-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        相关资源
        最近更新 更多