为了账号安全,请及时绑定邮箱和手机立即绑定

并发任务确定性地生成伪随机数

并发任务确定性地生成伪随机数

慕工程0101907 2021-08-14 15:59:03
我有一个协程返回伪随机字节列表import asyncioimport randomimport osasync 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 resultsloop = 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)))...列表总是不同的:任务基本上相互干扰,不再是确定性的。如何生成两个并发的伪随机数任务,其中每个伪随机数列表都具有确定性,就好像没有其他任务在运行一样?[我的用例:测试并发行为,使用大量伪随机数,以非确定性间隔生成,但希望伪随机数本身对于每个任务的每次测试运行都相同]
查看完整描述

2 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

从random模块文档:


该模块提供的函数实际上是 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


查看完整回答
反对 回复 2021-08-14
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

您可以使用random.getstateand random.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


查看完整回答
反对 回复 2021-08-14
  • 2 回答
  • 0 关注
  • 146 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号