【发布时间】:2017-07-11 15:57:03
【问题描述】:
我正在使用 Python 的新(ish)asyncio 东西,试图将其事件循环与传统线程结合起来。我编写了一个在自己的线程中运行事件循环的类,以隔离它,然后提供一个(同步)方法,在该循环上运行协程并返回结果。 (我意识到这使它成为一个毫无意义的例子,因为它必然会序列化所有内容,但它只是作为概念验证)。
import asyncio
import aiohttp
from threading import Thread
class Fetcher(object):
def __init__(self):
self._loop = asyncio.new_event_loop()
# FIXME Do I need this? It works either way...
#asyncio.set_event_loop(self._loop)
self._session = aiohttp.ClientSession(loop=self._loop)
self._thread = Thread(target=self._loop.run_forever)
self._thread.start()
def __enter__(self):
return self
def __exit__(self, *e):
self._session.close()
self._loop.call_soon_threadsafe(self._loop.stop)
self._thread.join()
self._loop.close()
def __call__(self, url:str) -> str:
# FIXME Can I not get a future from some method of the loop?
future = asyncio.run_coroutine_threadsafe(self._get_response(url), self._loop)
return future.result()
async def _get_response(self, url:str) -> str:
async with self._session.get(url) as response:
assert response.status == 200
return await response.text()
if __name__ == "__main__":
with Fetcher() as fetcher:
while True:
x = input("> ")
if x.lower() == "exit":
break
try:
print(fetcher(x))
except Exception as e:
print(f"WTF? {e.__class__.__name__}")
为了避免这听起来太像“代码审查”问题,asynchio.set_event_loop 的目的是什么,我在上面需要它吗?无论有没有,它都可以正常工作。此外,是否有循环级方法来调用协程并返回未来?用模块级函数来做这件事似乎有点奇怪。
【问题讨论】:
标签: python python-multithreading python-asyncio