【问题标题】:How to use python3 asyncio to do, well, async io?如何使用python3 asyncio来做async io?
【发布时间】:2020-02-26 12:11:38
【问题描述】:

我的python 3.6程序需要异步写一些文件,这样 它可以将写入与另一个线程上的计算重叠。 该程序使用 C 模块库来计算结构,并调用 该库中的函数以保存它。下面是一个草图:

async def save_thing(thing_ref):
    my_lib.save_thing(thing_ref)

def main():
    handles = []
    for i in [1, 2, 3]:
        thing_ref = my_lib.compute_thing(i)
        handle = save_thing(thing_ref)
        handles.append(handle)

    await_all(handles)
    # ... proceed with program ...

mylib.save_thing 释放 GIL:在进入时它调用 PyEval_SaveThread() 和 退出时它调用PyEval_RestoreThread()。我在上面明确省略了 增加thing_ref 的引用计数,但我希望我会管理引用 在save_thing 完成之前,保持thing_ref 存活是很重要的。

谁能帮我把那幅草图充实一下,给我看我的机器 需要包括使 my_lib.save_thing() 的主体在另一个线程上同时执行, 与python循环?我正在摸索试图理解角色 事件循环、asyncio 模块、GIL 和 python 线程。我怀疑简单地释放 GIL 不会导致主线程解释器在那时恢复, 我不清楚如何让它这样做。

【问题讨论】:

    标签: python-3.x async-await


    【解决方案1】:

    如果我理解正确并且 save_thing(thing_ref) 可以等待 那么你可以这样做

    import asyncio
    
    
    
    async def save_thing(thing_ref):
        await asyncio.sleep(1)                # so you can see this works
        # await my_lib.save_thing(thing_ref)  # if this is awaitable
        return thing_ref
    
    
    def compute_thing(i):
        return i
    
    
    
    
    def main():
        loop = asyncio.get_event_loop()
        handles = []
        for i in [1, 2, 3]:
            thing_ref = compute_thing(i)
            handle = loop.run_until_complete(save_thing(thing_ref))
            handles.append(handle)
        print(handles)
    
    
    if __name__ == "__main__":
        main()
    

    输出

    [1, 2, 3]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 2021-02-15
      • 2017-11-04
      相关资源
      最近更新 更多