python - 在自己的线程中运行事件循环

标签 python python-multithreading python-asyncio

我正在玩 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 的目的是什么?我是否需要在上面使用它?无论有无,它都可以正常工作。此外,是否有循环级别的方法来调用协程并返回 future ?使用模块级函数执行此操作似乎有点奇怪。

最佳答案

您需要使用 set_event_loop如果你调用get_event_loop任何地方,并希望它返回调用 new_event_loop 时创建的循环.

来自docs

If there’s need to set this loop as the event loop for the current context, set_event_loop() must be called explicitly.

由于您不调用 get_event_loop在您的示例中的任何位置,您都可以省略对 set_event_loop 的调用.

关于python - 在自己的线程中运行事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45039370/

相关文章:

Python asyncio : function or coroutine, 使用哪个?

python - 可以在 Python 中声明一个抽象异常吗?

python - 有没有一种简单的方法可以为 Tkinter 文本小部件制作 block 状插入光标?

python:tkinter 显示来自网络摄像头的视频并进行 QR 扫描

python - 如何对 aiohttp.web 应用程序进行单元测试

python - 如何在 Python 中异步接收来自多个 WebSocket 的数据?

python - python为什么显示 'list index out of range'错误?

python - 是否可以获取 tkinter 文本中标记的数字索引(位置)?

python - 绘制实时传感器数据时,PyQtGraph 停止更新并卡住

python - 如何在 fasta 文件中并行计算,其中每个处理器处理一个序列