我想使用ThreadPoolExecutor中的python coroutine来将一些阻止网络调用委托给单独的线程。但是,运行以下代码:
from concurrent.futures import ThreadPoolExecutor
import asyncio
def work():
# do some blocking io
pass
async def main():
executor = ThreadPoolExecutor()
await executor.submit(work)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
导致错误:
TypeError: object Future can't be used in 'await' expression
Future
对象是否等待?为什么说它们不是?
await
如何Future
executor.submit
executor.submit
对象返回?
Python 3.5.0
修改
使用!important
不是我的决定。这在几个库内部使用,如requests-futures
。我正在寻找一种方法来与协同程序中的那些模块互操作。
答案 0 :(得分:22)
您应该使用loop.run_in_executor
:
from concurrent.futures import ThreadPoolExecutor
import asyncio
def work():
# do some blocking io
pass
async def main(loop):
executor = ThreadPoolExecutor()
await loop.run_in_executor(executor, work)
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()
修改强>
concurrent.futures.Future
对象与asyncio.Future
不同。 asyncio.Future
旨在与事件循环一起使用,并且等待,而前者不是。 loop.run_in_executor
提供了两者之间必要的互操作性。
编辑#2
使用executor.submit不是我的决定。这在几个库内部使用,例如请求期货。我正在寻找一种方法来与协同程序中的那些模块互操作。
编辑#3
自python 3.5(docs)起,您可以使用asyncio.wrap_future(future, *, loop=None)
将concurrent.futures.Future
转换为asyncio.Future
。