如何在异步上下文中读取(hdf5)文件?

时间:2018-11-30 10:48:20

标签: python-3.x python-asyncio asgi starlette

最近我一直在玩python 3异步功能。总的来说,我对3.6语法不满意,当然,您获得的性能提升也很满意。在我看来,围绕ASGI标准发展的令人兴奋的项目之一是starlette。我有一个示例应用程序正在运行,我正在其中从hdf5文件中读取数据。 h5py目前尚不支持异步I / O。这让我想到了一个问题:我在这里所做的一切是否有意义?据我了解,这段代码毕竟是同步运行的。在异步上下文中进行I / O的推荐方法是什么?

async def _flow(indexes):
    print('received flow indexes %s ' %indexes)
    # uses h5py under the hood
    gr = GridH5ResultAdmin(gridadmin_f, results_f)
    t = gr.nodes.timeseries(indexes=indexes)
    data = t.only('s1').data
    # data is a numpy array
    return data['s1'].tolist()

@app.route('/flow_velocity')
async def flow_results(request):

    indexes_list = [[2,3,4,5], [6,7,8,9], [10,11,12,13]]

    tasks = []
    loop = asyncio.get_event_loop()
    t0 = datetime.datetime.now()
    for indexes in indexes_list:
        print('Start getting indexes %s' % indexes)
        # Launch a coroutine for each data fetch
        task = loop.create_task(_flow(indexes))
        tasks.append(task)

    # Wait on, and then gather, all data
    flow_data = await asyncio.gather(*tasks)
    dt = (datetime.datetime.now() - t0).total_seconds()
    print('elapsed time: {} [s]'.format(dt))

    return JSONResponse({'flow_velocity': flow_data})

记录:

INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
Start getting indexes "[2, 3, 4, 5]"
Start getting indexes "[6, 7, 8, 9]"
Start getting indexes "[10, 11, 12, 13]"
received flow indexes [2, 3, 4, 5] 
received flow indexes [6, 7, 8, 9] 
received flow indexes [10, 11, 12, 13]
elapsed time: 1.49779 [s]

1 个答案:

答案 0 :(得分:1)

不幸的是,使用h5py模块不能使用asyncio,这里的操作主要是顺序的,因为如果I / O部分不能异步完成,则其余部分您的异步代码没有太多意义

https://github.com/h5py/h5py/issues/837

该线程的摘要

  

因此添加异步支持存在两个独立的问题:

     
      
  1. asyncio目前明确不支持文件系统I / O,请参阅例如https://github.com/python/asyncio/wiki/ThirdParty#filesystemhttps://groups.google.com/forum/#!topic/python-tulip/MvpkQeetWZAWhat is the status of POSIX asynchronous I/O (AIO)?https://github.com/Tinche/aiofiles,它们是您想要的最接近的。
  2.   
  3. 所有I / O都是通过HDF5(库)完成的,因此您想要添加的任何异步支持都需要HDF5(库)的支持
  4.   
     

这基本上意味着h5py不太可能支持asyncio。

     

您可以尝试在线程中运行事物,但是不能保证它能正常运行,正如我提到的那样,HDF5控制I / O,并且您将要确保自己不会遇到任何锁定控件。您可能需要了解http://docs.h5py.org/en/latest/high/file.html#file-drivers中提到的哪种文件模式最适合您。也许您可以考虑其他选择,例如多处理或并发。