python 如何在Jupyter Notebook中使用Asyncio进行嵌套异步调用?

wnavrhmk  于 2023-02-02  发布在  Python
关注(0)|答案(1)|浏览(319)

我已经创建了一个Jupyter Notebook,它对一个模型代码的两个不同版本进行基准测试,通过运行一组示例问题来查看它们是否产生相同的结果。例如,我在一组示例问题(例如Example1到Example10)上运行参考模型“RF”和基准模型“BM”,然后比较结果,看看它们是否不同。
到目前为止,我设法让以下工作:

  • 循环查看示例问题
  • get RF and BM run以使用asyncio异步运行当前示例
  • 等待RF和BM完成
  • 收集结果并进行比较

但是不能让它以嵌套的方式运行这组示例,从而使每组示例都可以独立运行。
我有一个非常简单的版本:

#Ex_cases is a list of example cases defined elsewhere 
#RF is the reference model 
#BM is the benchmark model

def compare(RF, BM)
    #do some comparisons on the results 
    return comparison

async def Run_sim(model, case): #run the model for the specified case
    result = run_model(model,case)
    return result

for (i,n) in enumerate(Ex_cases)
    RF_task = asyncio.create_task(Run_sim(RF, Ex_cases[i]))
    BM_task = asyncio.create_task(Run_sim(RF, Ex_cases[i]))

    results = await asyncio.gather(RF_task,BM_task)
    RF_res = results[0]
    BM_res = results[1]

    comparison = compare(RF_res,BM_res)
    print(comparison)

上面的方法运行得相当好,运行时间减少了一半左右。我想弄清楚的是如何使for循环也异步,这样for循环的每次迭代都可以独立运行,但是循环中并行的RF和BM任务必须在到达比较函数之前运行完成。不幸的是,我发现异步文档对这项任务相当不透明。
提前感谢您的回答。

qybjjes1

qybjjes11#

for循环的主体 Package 为一个协程,并为所有协程调用asyncio.gather(),如下例所示(我更正了原始代码中的一个拼写错误,并进行了一些重构)。

async def run_sim(model, case):
    result = run_model(model, case)
    return result

async def run_sims_and_compare(case):
    RF_res, BM_res = await asyncio.gather(run_sim(RF, case), run_sim(BM, case))
    comparison = compare(RF_res, BM_res)
    print(comparison)

await asyncio.gather(*[run_sims_and_compare(case) for case in Ex_cases])

顺便说一句,你可以直接向asyncio.gather()传递一个协程。不要忘了你这样做只使用了一个线程。请看这个使用多线程。但我不知道Jupyter是否完全支持它。

相关问题